Recursive functions with multiple arguments Haskell - haskell

A really simple question: I want to implement the multiplication of 2 integers in Haskell.
What I wrote doesn't compile:
mult :: Int -> Int -> Int
mult x 1 = x
mult 1 y = y
mult x y = x + (mult x-1 y)
The problem is the last statement. I've tried writing it as:
mult x y = x + (mult x-1 y)
and also
mult x y = x + (mult(x-1,y))
The error I get is:
Couldn't match expected type `Int' with actual type `Int -> Int'
In the return type of a call of `mult'
I don't know why the compiler would say that mult returns an Int -> Int when it clearly returns an Int.

You have to put x-1 into brackets! Like so
mult x y = x + (mult (x-1) y)
By the way, this does not compute the multiplication of x and y :-)
Try some examples... it's a little mistake only.

In
mult x y = x + (mult x-1 y)
the expression within the parentheses parses as:
(mult x) - (1 y)
And so the compiler thinks the first argument to (-) is mult x, which is an Int -> Int function because just one argument (rather than two) is being passed. Instead, you want:
mult x y = x + mult (x-1) y

It's a simple parser issue. The compiler is reading mult x-1 y as ((-) (mult x) y) when what you mean is mult (x-1) y. Function application binds very tightly in Haskell, so it's sometimes better to use too many parentheses rather too few, especially while you're still learning the basics of the language.
The error occurs because the type of (mult x) is Int -> Int but the type of y is Int, and you can't subtract those two things.

Related

Using `newtype` to wrap other types

I'm trying to understand newtype and thought this would work:
module NT where
newtype X = X Double
newtype Y = Y Double
doit :: X -> Y -> Double
doit x y = x + y
x = X 1.1
y = Y 2.2
-- doit x y should work
-- doit y x should error
The first error produced is:
NT.hs:7:12: error:
• Couldn't match expected type ‘Double’ with actual type ‘X’
• In the expression: X x + Y y
In an equation for ‘doit’: doit x y = X x + Y y
|
7 | doit x y = X x + Y y
|
I get that the types don't match, I just don't understand how to get around it. I thought wrapping Double like this could be used to prevent the mixup of x and y in doit.
Is this true, or am I misunderstanding?
You need to “unwrap” the newtype before + can work.
doit :: X -> Y -> Double
doit (X x) (Y y) = x + y
Here, I am using pattern matching to unwrap the Double inside each argument. Here, x and y are both Double, so you can just add them with x + y.
You unwrap the elements out of the data constructor with pattern matching:
doit :: X -> Y -> Double
doit (X x) (Y y) = x + y
Here the x and y are thus Doubles, since the parameters the X and Y data constructor wrap are Doubles as well.

Parse error in pattern n

I'm new to haskell.
Got a parse error and dont know what is wrong.
fromDecTo :: (Int -> Int) -> [Int]
fromDecTo (n x) | (n < x) = [n]
| otherwise = fromDecTo (n `div` x) ++ [n `mod` x]
This should convert a decimal number into a number with base x (a.e. hexadecimal).
Please help me.
fromDecTo :: (Int -> Int) -> [Int]
This is a function having one argument, a function from integers to integers. This is not what you want: you want a function having two arguments, i.e.
fromDecTo :: Int -> Int -> [Int]
Similarly, the pattern
fromDecTo (n x)
expresses the result of applying a function n to x and then applying fromDecToto the result. This is not what you want, taking two arguments is done with
fromDecTo n x
As a final note, even if it not customary to do so, it is possible to add parentheses, but with the opposite association. The same type shown above could be written
fromDecTo :: Int -> (Int -> Int)
which stresses the fact that functions are curried in Haskell: a binary function is actually a function taking only one argument, the first, and returning a function taking one other argument, the second, and finally returning the result.
Similarly, instead of
fromDecTo n x
we could write
(fromDecTo n) x
since n is applied to fromDecTo first, and then x after that.
You have several issues in your code. Here is what you want to achieve:
fromDecTo :: Int -> Int -> [Int]
fromDecTo n x | (n < x) = [n]
| otherwise = fromDecTo (n `div` x) x ++ [n `mod` x]

Defining division using Haskell

I decided it would be cool to learn Haskell by recreating arithmetic using only the Succ function, or other functions I've defined, and the Integer number type. So far I've managed to (re)create Add, Subtract, and Multiply, only for Integers. I've created a predecessor function as well.
However, I want division over rational numbers, but I don't want to borrow anymore types. What I'd like to do is use a pair of Integers to define the numerator and denominator and work from there. What's cool is that if I figure this out, the complex plane and operations on it should be a similar.
(I know that using the Integer type is technically cheating, and that I don't need it. But if I do fancy things like Peano arithmetic (?) I also have to figure out how get the system to represent the solution with pretty digits and the like. )
How would I define a custom "rational" number type as a pair of two Integers?
I'd go about it like so, the traditional inductive way:
data N = Z | S N deriving (Show, Eq)
cmp Z Z = EQ -- of course, could have derived Ord
cmp Z _ = LT
cmp (S _) Z = GT
cmp (S x) (S y) = cmp x y
add Z x = x
add (S x) y = S $ add x y
sub Z x = Z -- have to do something to negative numbers
sub x Z = x
sub (S x) (S y) = sub x y
divi x y | cmp x y == LT = (x, Z)
divi x y = fmap S $ divi (sub x y) y -- dividing by Z will not terminate
Then we have
Prelude> divi (S $ S $ S Z) (S $ S Z) -- 3 / 2 == (1,1)
(S Z,S Z)
Prelude> divi (S $ S $ S $ S Z) (S $ S Z) -- 4 / 2 == (0, 2)
(Z,S (S Z))
for some background on how to encode integer arithmetic in rewriting
(and you can easily translate this into first-order functional programs), see
Walters and Zantema, Rewrite Systems for Integer Arithmetic,
http://www.cs.uu.nl/research/techreps/repo/CS-1994/1994-43.pdf
Contejean, Marche, Rabehasaina, Rewrite Systems for natural, integer, and rational Arithmetic,
https://www.lri.fr/~marche/articles/rta97.ps.gz
and references cited there.

Reusing patterns in pattern guards or case expressions

My Haskell project includes an expression evaluator, which for the purposes of this question can be simplified to:
data Expression a where
I :: Int -> Expression Int
B :: Bool -> Expression Bool
Add :: Expression Int -> Expression Int -> Expression Int
Mul :: Expression Int -> Expression Int -> Expression Int
Eq :: Expression Int -> Expression Int -> Expression Bool
And :: Expression Bool -> Expression Bool -> Expression Bool
Or :: Expression Bool -> Expression Bool -> Expression Bool
If :: Expression Bool -> Expression a -> Expression a -> Expression a
-- Reduces an Expression down to the simplest representation.
reduce :: Expression a -> Expression a
-- ... implementation ...
The straightforward approach to implementing this is to write a case expression to recursively evaluate and pattern match, like so:
reduce (Add x y) = case (reduce x, reduce y) of
(I x', I y') -> I $ x' + y'
(x', y') -> Add x' y'
reduce (Mul x y) = case (reduce x, reduce y) of
(I x', I y') -> I $ x' * y'
(x', y') -> Mul x' y'
reduce (And x y) = case (reduce x, reduce y) of
(B x', B y') -> B $ x' && y'
(x', y') -> And x' y'
-- ... and similarly for other cases.
To me, that definition looks somewhat awkward, so I then rewrote the definition using pattern guards, like so:
reduce (Add x y) | I x' <- reduce x
, I y' <- reduce y
= I $ x' + y'
I think this definition looks cleaner compared to the case expression, but when defining multiple patterns for different constructors, the pattern is repeated multiple times.
reduce (Add x y) | I x' <- reduce x
, I y' <- reduce y
= I $ x' + y'
reduce (Mul x y) | I x' <- reduce x
, I y' <- reduce y
= I $ x' * y'
Noting these repeated patterns, I was hoping there would be some syntax or structure that could cut down on the repetition in the pattern matching. Is there a generally accepted method to simplify these definitions?
Edit: after reviewing the pattern guards, I've realised they don't work as a drop-in replacement here. Although they provide the same result when x and y can be reduced to I _, they do not reduce any values when the pattern guards do not match. I would still like reduce to simplify subexpressions of Add et al.
One partial solution, which I've used in a similar situation, is to extract the logic into a "lifting" function that takes a normal Haskell operation and applies it to your language's values. This abstracts over the wrappping/unwrapping and resulting error handling.
The idea is to create two typeclasses for going to and from your custom type, with appropriate error handling. Then you can use these to create a liftOp function that could look like this:
liftOp :: (Extract a, Extract b, Pack c) => (a -> b -> c) ->
(Expression a -> Expression b -> Expression c)
liftOp err op a b = case res of
Nothing -> err a' b'
Just res -> pack res
where res = do a' <- extract $ reduce' a
b' <- extract $ reduce' b
return $ a' `op` b'
Then each specific case looks like this:
Mul x y -> liftOp Mul (*) x y
Which isn't too bad: it isn't overly redundant. It encompasses the information that matters: Mul gets mapped to *, and in the error case we just apply Mul again.
You would also need instances for packing and unpacking, but these are useful anyhow. One neat trick is that these can also let you embed functions in your DSL automatically, with an instance of the form (Extract a, Pack b) => Pack (a -> b).
I'm not sure this will work exactly for your example, but I hope it gives you a good starting point. You might want to wire additional error handling through the whole thing, but the good news is that most of that gets folded into the definition of pack, unpack and liftOp, so it's still pretty centralized.
I wrote up a similar solution for a related (but somewhat different) problem. It's also a way to handle going back and forth between native Haskell values and an interpreter, but the interpreter is structured differently. Some of the same ideas should still apply though!
This answer is inspired by rampion's follow-up question, which suggests the following function:
step :: Expression a -> Expression a
step x = case x of
Add (I x) (I y) -> I $ x + y
Mul (I x) (I y) -> I $ x * y
Eq (I x) (I y) -> B $ x == y
And (B x) (B y) -> B $ x && y
Or (B x) (B y) -> B $ x || y
If (B b) x y -> if b then x else y
z -> z
step looks at a single term, and reduces it if everything needed to reduce it is present. Equiped with step, we only need a way to replace a term everywhere in the expression tree. We can start by defining a way to apply a function inside every term.
{-# LANGUAGE RankNTypes #-}
emap :: (forall a. Expression a -> Expression a) -> Expression x -> Expression x
emap f x = case x of
I a -> I a
B a -> B a
Add x y -> Add (f x) (f y)
Mul x y -> Mul (f x) (f y)
Eq x y -> Eq (f x) (f y)
And x y -> And (f x) (f y)
Or x y -> Or (f x) (f y)
If x y z -> If (f x) (f y) (f z)
Now, we need to apply a function everywhere, both to the term and everywhere inside the term. There are two basic possibilities, we could apply the function to the term before applying it inside or we could apply the function afterwards.
premap :: (forall a. Expression a -> Expression a) -> Expression x -> Expression x
premap f = emap (premap f) . f
postmap :: (forall a. Expression a -> Expression a) -> Expression x -> Expression x
postmap f = f . emap (postmap f)
This gives us two possibilities for how to use step, which I will call shorten and reduce.
shorten = premap step
reduce = postmap step
These behave a little differently. shorten removes the innermost level of terms, replacing them with literals, shortening the height of the expression tree by one. reduce completely evaluates the expression tree to a literal. Here's the result of iterating each of these on the same input
"shorten"
If (And (B True) (Or (B False) (B True))) (Add (I 1) (Mul (I 2) (I 3))) (I 0)
If (And (B True) (B True)) (Add (I 1) (I 6)) (I 0)
If (B True) (I 7) (I 0)
I 7
"reduce"
If (And (B True) (Or (B False) (B True))) (Add (I 1) (Mul (I 2) (I 3))) (I 0)
I 7
Partial reduction
Your question implies that you sometimes expect that expressions can't be reduced completely. I'll extend your example to include something to demonstrate this case, by adding a variable, Var.
data Expression a where
Var :: Expression Int
...
We will need to add support for Var to emap:
emap f x = case x of
Var -> Var
...
bind will replace the variable, and evaluateFor performs a complete evaluation, traversing the expression only once.
bind :: Int -> Expression a -> Expression a
bind a x = case x of
Var -> I a
z -> z
evaluateFor :: Int -> Expression a -> Expression a
evaluateFor a = postmap (step . bind a)
Now reduce iterated on an example containing a variable produces the following output
"reduce"
If (And (B True) (Or (B False) (B True))) (Add (I 1) (Mul Var (I 3))) (I 0)
Add (I 1) (Mul Var (I 3))
If the output expression from the reduction is evaluated for a specific value of Var, we can reduce the expression all the way to a literal.
"evaluateFor 5"
Add (I 1) (Mul Var (I 3))
I 16
Applicative
emap can instead be written in terms of an Applicative Functor, and postmap can be made into a generic piece of code suitable for other data types than expressions. How to do so is described in this answer to rampion's follow-up question.

How is Ratio implemented in Haskell?

This is something I have been confused about for a while and I am not sure how I can learn more about it. Let's say I have the following program:
main :: IO ()
main = do
x <- liftM read getLine
y <- liftM read getLine
print (x % y)
If I run this with the input 6 and 2, it will print 3 % 1.
At what point does the simplification happen (namely the division by the gcd)? Is it implemented in show? If so, then is the underlying representation of the rational still 6 % 2? If not, then does (%) do the simplification? I was under the impression that (%) is a data constructor, so how would a data constructor do anything more than "construct"? More importantly, how would I actually go about doing similar things with my own data constructors?
I appreciate any help on the topic.
Ratio is actually implemented in GHC.Real (on GHC, obviously), and is defined as
data Ratio a = !a :% !a deriving (Eq)
The bangs are just there for strictness. As you can see, the function % is not a data constructor, but :% is. Since you aren't supposed to construct a Ratio directly, you use the % function, which calls reduce.
reduce :: (Integral a) => a -> a -> Ratio a
{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}
reduce _ 0 = ratioZeroDenominatorError
reduce x y = (x `quot` d) :% (y `quot` d)
where d = gcd x y
(%) :: (Integral a) => a -> a -> Ratio a
x % y = reduce (x * signum y) (abs y)
The rule is that if an operator starts with a colon :, then it is a constructor, otherwise it is just a normal operator. In fact, this is part of the Haskell standard, all type operators must have a colon as their first character.
You can just look at the source to see for yourself:
instance (Integral a) => Num (Ratio a) where
(x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
(x:%y) - (x':%y') = reduce (x*y' - x'*y) (y*y')
(x:%y) * (x':%y') = reduce (x * x') (y * y')
negate (x:%y) = (-x) :% y
abs (x:%y) = abs x :% y
signum (x:%_) = signum x :% 1
fromInteger x = fromInteger x :% 1
reduce :: (Integral a) => a -> a -> Ratio a
reduce _ 0 = ratioZeroDenominatorError
reduce x y = (x `quot` d) :% (y `quot` d)
where d = gcd x y

Resources