We usually see =
, <-
, <=
in haskell. What's the difference between these?

- 117,950
- 5
- 174
- 319

- 97
- 1
- 1
- 8
-
Partial duplicate of http://stackoverflow.com/questions/28624408/equal-vs-left-arrow-symbols-in-haskell – chi Aug 25 '16 at 11:40
2 Answers
=
means defined to be equal. I.e., if I writex = 5
somewhere in a file, I can then at any other point (within the same scope) replace
5
withx
and vice versa – they're the same thing. (And will always remain the same.) The definition can however also refer back to the name you're binding it to, to give recursive computations likefibonacci :: [Integer] fibonacci = 0 : 1 : zipWith (+) fibs (tail fibonacci)
In this case, you could still at any point replace
fibonacci
with0 : 1 : zipWith (+) fibs (tail fibonacci)
, though of course you would need to repeat the process infinitely.
A=
definition can stand either at the top-level, i.e. in a line of its own in the module, or within alet
orwhere
block:silly :: Integer -> Integer silly x = y where y = let z = x + 1 in z - 1
Here,
silly
is a top-level binding (with a function argument),y
is awhere
binding, andz
is alet
binding.<-
means essentially defined as the result of, meaning the result of a monadic computation. It usually stands in ado
block, for instance:main :: IO () main = do putStrLn "Enter your name, please" userName <- getLine putStrLn $ "Hello, " ++ userName
Note that this is very different from
main = do putStrLn "Enter your name, please" let userName' = getLine putStrLn $ "Hello, " ++ userName' -- error here
What this would do is not define
userName
as the string entered by the user, but as the action that requests a string to be entered.userName
is aString
, butuserName' :: IO String
.<-
is also used in list comprehensions:squareNums :: [Integer] squareNums = [x^2 | x <- [0..]]
It may seem that this does something different from
userName <- getLine
, but actually it does the same thing, just in a different monad (list instead of IO). In fact I could also write that assquareNums = do x <- [0..] return $ x^2
There's also a third use of
<-
which is really different: pattern guards, but these are not so common.<=
is just a library function (in infix-operator form). This is also the case for most other symbolic “syntax” you'll encounter in Haskell. You can ask Hayoo about such operators, it will tell you that<=
is defined in theData.Ord
module and is simply the less-that-or-equal comparison operator.
You can also define such operators yourself – if it weren't already in the standard library, I could easily define(<=) :: Ord a => a -> a -> Bool x <= y = not $ x > y
Incidentally, that
=>
in the signature is something completely different – this is again built-in syntax. There was also a question about that this week.

- 7,431
- 18
- 59
- 84

- 117,950
- 5
- 174
- 319
=
is a binding. It binds a name to a value/expression. You use it for top-level bindings, in let blocks and in where blocks.
myfun x = let y = x + 1
in z y
where z n = n * n
<-
is a monadic extraction. It's part of the do
notation and introduces a name bound to the contents of a monad.
main = do
name <- getLine
putStrLn ("Hello, " ++ name)
<=
is the less-or-equal operator defined in the Cmp
typeclass.
message x = if x < 18 then "No, you can't vote." else "Go ahead."

- 117,950
- 5
- 174
- 319

- 69,373
- 8
- 123
- 157
-
It's very clear! Thanks a lot! May I ask what is a 'top-level binding'? What's the difference between a top-level binding and other bindings? – Mia.M Aug 25 '16 at 10:21
-
Top-level bindings are those directly at file level (or in a module's where block). The only real difference to other bindings is their visibility. – Sebastian Redl Aug 25 '16 at 11:02
-
I think *"monadic extraction"* should really be *"monadic binding"*. – Will Ness Aug 31 '16 at 08:58