`let .. in do` 和 Haskell Monads 中的 `<-` 符号有什么区别?
What is the difference between `let .. in do` and `<-` notation in Haskell Monads?
我正在尝试实现一个将字符串转换为 Maybe Ints 列表的函数,例如readInts "1 2 42 foo" = [Just 1,Just 2,Just 42,Nothing]
.
我的第一个方法是:
readInts (s::String) = do {
ws <- words s;
return (map (readMaybe::(String -> Maybe Int)) ws)
}
这导致了以下错误:
lab_monad.hs:20:52:
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: String
In the second argument of ‘map’, namely ‘ws’
In the first argument of ‘return’, namely
‘(map (readMaybe :: String -> Maybe Int) ws)’
Failed, modules loaded: none.
我接下来尝试(并成功)的是:
readInts (s::String) = do {
let ws = (words s) in do
return (map (readMaybe::(String -> Maybe Int)) ws)
}
我这里的问题是,words s
显然是[String]
类型的。为什么解释器说它是String
?我对 <-
运算符有什么不了解?
ws <- words s
,在列表 monad 中,非确定性地分配 one 从 words s
到 ws
的单词;剩下的代码只处理那个单词,return
函数 "magically" 将处理 all 个单词的结果组合到结果列表中。
readInts s = do
ws <- words s -- ws represents *each* word in words s
return (readMaybe ws)
do
表示法只是使用 monadic 的语法糖 bind
:
readInts s = words s >>= (\ws -> return (readMaybe ws))
不使用列表的 Monad
实例,您可以使用 map
对每个单词应用相同的功能。
readInts s = map readMaybe (words s)
另一方面,let
只是为要在另一个表达式中使用的更复杂的表达式提供名称。它可以被认为是定义和立即应用匿名函数的语法糖。也就是说,
let x = y + z in f x
等同于
(\x -> f x) (y + z)
^ ^ ^
| | |
| | RHS of let binding
| part after "in"
LHS of let binding
具有多个绑定的 let
语句等同于嵌套的 let
语句:
let x = y + z
a = b + c
in x + a
等同于
let x = y + z
in let a = b + c
in x + a
脱糖到
(\x -> (\a -> x + a)(b + c))(y + z)
我正在尝试实现一个将字符串转换为 Maybe Ints 列表的函数,例如readInts "1 2 42 foo" = [Just 1,Just 2,Just 42,Nothing]
.
我的第一个方法是:
readInts (s::String) = do {
ws <- words s;
return (map (readMaybe::(String -> Maybe Int)) ws)
}
这导致了以下错误:
lab_monad.hs:20:52:
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: String
In the second argument of ‘map’, namely ‘ws’
In the first argument of ‘return’, namely
‘(map (readMaybe :: String -> Maybe Int) ws)’
Failed, modules loaded: none.
我接下来尝试(并成功)的是:
readInts (s::String) = do {
let ws = (words s) in do
return (map (readMaybe::(String -> Maybe Int)) ws)
}
我这里的问题是,words s
显然是[String]
类型的。为什么解释器说它是String
?我对 <-
运算符有什么不了解?
ws <- words s
,在列表 monad 中,非确定性地分配 one 从 words s
到 ws
的单词;剩下的代码只处理那个单词,return
函数 "magically" 将处理 all 个单词的结果组合到结果列表中。
readInts s = do
ws <- words s -- ws represents *each* word in words s
return (readMaybe ws)
do
表示法只是使用 monadic 的语法糖 bind
:
readInts s = words s >>= (\ws -> return (readMaybe ws))
不使用列表的 Monad
实例,您可以使用 map
对每个单词应用相同的功能。
readInts s = map readMaybe (words s)
另一方面,
let
只是为要在另一个表达式中使用的更复杂的表达式提供名称。它可以被认为是定义和立即应用匿名函数的语法糖。也就是说,
let x = y + z in f x
等同于
(\x -> f x) (y + z)
^ ^ ^
| | |
| | RHS of let binding
| part after "in"
LHS of let binding
具有多个绑定的 let
语句等同于嵌套的 let
语句:
let x = y + z
a = b + c
in x + a
等同于
let x = y + z
in let a = b + c
in x + a
脱糖到
(\x -> (\a -> x + a)(b + c))(y + z)