[英]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
,在单子列表中,不确定地将words s
一个单词分配给ws
; 剩下的代码仅使用该单词, return
函数“神奇地”将所有单词的运算结果组合到结果列表中。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.