Haskell do-block return error - haskell

I have a simple function:
func :: Int
func = do
x <- 1
return x
But I got an error message as follows:
Couldn't match type ‘m0 b0’ with ‘Int’
What's wrong with my function?

There are two problems with your code:
The right side of <- must have the type m a where a is an arbitrary type (that then becomes the type of the left side) and m is the monad that the do-block belongs to. In your case the type of the right side is 1, which does not have that type.
If all you want to do is to bind a value to x, you need to use let x = 1, not <-.
The type of return is Monad m => a -> m a, so if we take the type of x to be Int, the type of return x is Monad m => m Int. But according to your type signature, you just want the type to be Int, not m Int. Therefore you shouldn't use return (or do-notation for that matter).
The correct way to write the definition that you're trying to write would be:
f = 1
or if you want to have a local x
f =
let x = 1 in
x
or
f = x
where x = 1

Related

How can I sum up Int and Int64?

I have this code:
tzDiff :: Int
tzDiff = 4 * 60 * 60
mySysTm :: IO Int64
mySysTm = do
st <- getSystemTime
pure $ systemSeconds st
I want to sum up these values.
main = do
a1 <- mySysTm
let res = tzDiff + mySysTm
===>
Couldn't match expected type ‘Int64’ with actual type ‘Int’
How can I sum them up? Without having to change the return type of tzDiff to be Int64 in the function definition because it doesn't need to be Int64
I've tried this - it didn't work due to the same error:
let res = (tzDiff :: Int64) + mySysTm
Why not?
I've tried this - it didn't work due to the same error:
let res = (tzDiff :: Int64) + mySysTm
Because Haskell has a strongly typed type system, which means you can not implicitly convert types from one item to another. Just trying to redeclare it another type will not help either. You should use functions to convert data from one type to another.
We can for example convert an Int to an Int64 with fromIntegral :: (Integral a, Num b) => a -> b:
main = do
a1 <- mySysTm
let res = fromIntegral tzDiff + mySysTm
putStrLn (show res)
because (+) has as type (+) :: Num a => a -> a -> a, so it always sums up two objects of the same type, and these types are members of the Num typeclass. Since it knows that mySysTm is an Int64, it thus knows that the result should be an Int64. Since tzDiff is an Int, it thus knows that it should convert an Int to an Int64.
The fromIntegral is defined in the Num typeclass, so all types that implement the Num typeclass, need to provide a definition for fromIntegral.
let res = (tzDiff :: Int64) + mySysTm
...
Why not?
Because earlier you said
tzDiff :: Int
One value can't be of two different types at the same time.
Use fromIntegral :: (Num b, Integral a) => a -> b instead, like
let res = fromIntegral tzDiff + mySysTm
Because the type of + is (+) :: a -> a -> a, it means that both of its operands must have the same type.
This is already evident in the code even before its compilation, let alone its execution.
fromIntegral is not a run-time type conversion operation. It is a function polymorphic in its return type. The compiler sees it, and interprets the code accordingly.

Difference between -> and => symbols. What do they mean?

In Haskell, when we talk type declaration.
I've seen both -> and =>.
As an example: I can make my own type declaration.
addMe :: Int -> Int -> Int
addMe x y = x + y
And it works just fine.
But if we take a look at :t sqrt we get:
sqrt :: Floating a => a -> a
At what point do we use => and when do we use ->?
When do we use "fat arrow" and when do we use "thin arrow"?
-> is for explicit functions. I.e. when f is something that can be written in an expression of the form f x, the signature must have one of these arrows in it†. Specifically, the type of x (the argument) must appear to the left of a -> arrow.
It's best to not think of => as a function arrow at all, at least at first‡. It's an implication arrow in the logical sense: if a is a type with the property Floating a, then it follows that the signature of sqrt is a -> a.
For your addMe example, which is a function with two arguments, the signature must always have the form x -> y -> z. Possibly there can also be a q => in front of that; that doesn't influence the function-ishness, but may have some saying in what particular types are allowed. Generally, such constraints are not needed if the types are already fixed and concrete. Like, you could in principle impose a constraint on Int:
addMe :: Num Int => Int -> Int -> Int
addMe x y = x + y
...but that doesn't really accomplish anything, because everybody knows that the particular type Int is an instance of the Num class. Where you need such constraints is when the type is not fixed but a type variable (i.e. lowercase), i.e. if the function is polymorphic. You can't just write
addMe' :: a -> a -> a
addMe' x y = x + y
because that signature would suggest the function works for any type a whatsoever, but it can't work for all types (how would you add, for example, two strings? ok perhaps not the best example, but how would you multiply two strings?)
Hence you need the constraint
addMe' :: Num a => a -> a -> a
addMe' x y = x + y
This means, you don't care what exact type a is, but you do require it to be a numerical type. Anybody can use the function with their own type MyNumType, but they need to ensure that Num MyNumType is fulfilled: then it follows that addMe' can have signature MyNumType -> MyNumType -> MyNumType.
The way to ensure this is to either use a standard type which you know to be numerical, for instance addMe' 5.9 3.7 :: Double would work, or give an instance declaration for your custom type and the Num class. Only do the latter if you're sure it's a good idea; usually the standard num types are all you'll need.
†Note that the arrow may not be visible in the signature: it's possible to have a type synonym for a function type, for example when type IntEndofunc = Int -> Int, then f :: IntEndofunc; f x = x+x is ok. But you can think of the typedef as essentially just a syntactic wrapper; it's still the same type and does have the arrow in it.
‡It so happens that logical implication and function application can be seen as two aspects of the same mathematical concept. Furthermore, GHC actually implements class constraints as function arguments, so-called dictionaries. But all this happens behind the scenes, so if anything they're implicit functions. In standard Haskell, you will never see the LHS of a => type as the type of some actual argument the function is applied to.
The "thin arrow" is used for function types (t1 -> t2 being the type of a function that takes a value of type t1 and produces a value of type t2).
The "fat arrow" is used for type constraints. It separates the list of type constraints on a polymorphic function from the rest of the type. So given Floating a => a -> a, we have the function type a -> a, the type of a function that can take arguments of any type a and produces a result of that same type, with the added constraint Floating a, meaning that the function can in fact only be used with types that implement the Floating type class.
the -> is the constructor of functions and the => is used to constraints, a sort of "interface" in Haskell called typeclass.
A little example:
sum :: Int -> Int -> Int
sum x y = x + y
that function only allows Int types, but if you want a huge int or a small int, you probably want Integer, and how to tell it to use both?
sum2 :: Integral a => a -> a -> a
sum2 x y = x + y
now if you try to do:
sum2 3 1.5
it will give you an error
also, you may want to know if two data are equals, you want:
equals :: Eq a => a -> a -> Bool
equals x y = x == y
now if you do:
3 == 4
that's ok
but if you create:
data T = A | B
equals A B
it will give to you:
error:
• No instance for (Eq T) arising from a use of ‘equals’
• In the expression: equals A B
In an equation for ‘it’: it = equals A B
if you want for that to work, you must just do:
data T = A | B deriving Eq
equals A B
False

Understanding function signature

I was reading a paper and one of the most fundamental parts of it is the following function, written in Haskell:
fixP :: Eq a => (Parser a -> Parser a) -> Parser a
fixP h x = fixS f
where f s = h p x
where p y = if x == y then s
else fixP h y
My Haskell is rusty. As I understand it fixP takes 1 argument which is a function Parser a -> Parser a, where a is constrained to have equality defined. However the pattern matches 2 arguments, h and x. What is x referring to?
Additional type signatures involved:
type Parser a = State -> Set (a,State)
type State = String
type Set a = [a]
fixS :: Eq a => (Set a -> Set a) -> Set a
After reading and understanding the answer and for anyone interested; here's the same function written in javascript:
function fixP(h) {
return function(x) {
var f = function(s) {
var p = function(y) {
if(x == y) {
return s;
} else {
return fixP(h)(y);
}
};
return h(p)(x);
};
return fixS(f);
};
}
Note that fixP h has type Parser a. Since Parser a is a synonym for State -> Set (a, State), we see that fixP h is in fact a function:
(fixP h) :: State -> Set (a, State)
We can therefore apply this function to some argument x of type State. That looks like (fixP h) x. Since function application is left associative , (fixP h) x is the same as fixP h x.
In words: To define what fixP is, we define what it does to arguments, i.e. we define what fixP h is. Since fixP h is itself a function, we need to define it. We define it by specifying what it does to arguments, i.e. we define what (fixP h) x is. Left associativity of function application means the latter can be written fixP h x.
As to the question "what's x?": Its type is State, so it smells like some sort of parser state, which according to the type synonyms you gave is a string. Exactly what that string's role is, though, is not clear just from the types :)
Simple explanation: Parser a is a type like this:
type Parser a = (String -> a)
This code then
module Main where
type NT a = (Int -> a)
f :: (NT a -> NT a) -> NT a
f h x = undefined
g :: NT Double
g 0 = 0.0
g _ = 1.0
main = undefined
typechecks well.

Converting types in Haskell

I'm working on a conversion problem for homework, and am a complete Haskell newbie, so bear with me. On one of them, it asks us to attempt to get the type of a function to be:
fc :: (Bool, [Char]) -> Int -> Integer -> [Bool]
Without worrying about what the actual function does or anything. These functions will not be run, it is just a test to see if we can convert types correctly. So far the furthest I can get is this:
fc :: (Bool, [Char]) -> Int
fc (x, y) = ord (head y)
Where I am turning it into an Int. When I try to turn it into an Integer using the toInteger function, it gives me:
Couldn't match expected type `Int -> Integer'
with actual type `Integer'
In the return type of a call of `toInteger'
Probable cause: `toInteger' is applied to too many arguments
In the expression: toInteger (ord (head y))
Any tips for the new guy?
Edit:
What I have been trying, for reference, is:
fc :: (Bool, [Char]) -> Int -> Integer
fc (x, y) = toInteger (ord (head y))
And I am getting the error above.
Your type signature is wrong. If you convert something you can't write it into the type signature. Only the last one is the return type. The others are parameter types.
Follow these:
fc::(Bool,[Char])->Integer
fc (x,y) = toInteger . ord . head $ y
fc::(Bool,[Char])->Int->Integer--
fc (x,y) n = if n == w then n else w
where w = toInteger . ord . head $ y
Edit:
The others mentioned currying what is absolutely correct if your teacher expect it. But the conversions doesn't take place in the type sign.
As n.m. says, the idea this is getting at is called currying. Basically, in Haskell, any function takes a single value and returns a single value: a -> b.
So, given this restriction, how can we implement functions like addition, which need two parameters? The answer is that we implement a function which takes a number, and returns another function which takes a number and returns a number. Laying it out this way might clarify things:
add :: Int -> Int -> Int
add x = f where f y = x + y
(which is equivalent to add x y = x + y, as well as add = (+)).
In your case, you should read the error carefully: Couldn't match expected type Int -> Integer with actual type Integer In the return type of a call of toInteger means that Haskell is expecting fc to return a value of type Int -> Integer, because that's what your type signature says, but the definition you've provided will always produce a value of type Integer.

Data initialization and data members change in Haskell

I'm new to Haskell and I cannot figure out how you declare a "Data" type and how you can initialize a variable with that type. I'd also like to know how can I change the values of certain members of that variable. For exaple :
data Memory a = A
{ cameFrom :: Maybe Direction
, lastVal :: val
, visited :: [Direction]
}
Direction is a Data type that contains N,S,E,W
val is a Type int
init :: Int -> a
init n = ((Nothing) n []) gives me the following error:
The function `Nothing' is applied to two arguments,
but its type `Maybe a0' has none
In the expression: ((Nothing) n [])
In an equation for `init': init n = ((Nothing) n [])
how can I fix this ?
UPDATE: That did it, thank you very much, but now i have another issue
move :: val -> [Direction] -> Memory -> Direction
move s cs m | s < m.lastVal = m.cameFrom
| ...
this gives me the following error:
Couldn't match expected type `Int' with actual type `a0 -> c0'
Expected type: val
Actual type: a0 -> c0
In the second argument of `(<)', namely `m . lastVal'
In the expression: s < m . lastVal
UPDATE 2: Again, that helped me a lot, thank you very much
Also, I have another question (sorry for being such a bother)
How do I adress only an element of a type
For example if I have
Type Cell = (Int, Int)
Type Direction = (Cell, Int)
how do I proceed if I want to compare a Cell variable with the Cell element of a Direction variable?
As to the update. The syntax
m.lastVal
and
m.cameFrom
is not what you want. Instead
move s cs m | s < lastVal m = cameFrom m
accessors are just functions, so used in prefix form. The . in Haskell is used for namespace resolution (which is not path dependent) and for function composition
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)
To initialise:
init :: Int -> Memory Int
init n = A {cameFrom = Nothing, lastVal = n, visited = []}
To change values: strictly speaking you don't change values, you return another different value, like this:
toGetBackTo :: Direction -> Memory a -> Memory a
toGetBackTo dir memory = memory {cameFrom = Just dir, visited = dir : visited memory}

Resources