[英]What is the difference between `let .. in do` and `<-` notation in Haskell Monads?
I'm trying to implement a function which converts a string to a list of Maybe Ints, eg readInts "1 2 42 foo" = [Just 1,Just 2,Just 42,Nothing]
. 我正在尝试实现一个将字符串转换为Maybe Ints列表的函数,例如readInts "1 2 42 foo" = [Just 1,Just 2,Just 42,Nothing]
。
My first aproach was: 我的第一个方法是:
readInts (s::String) = do {
ws <- words s;
return (map (readMaybe::(String -> Maybe Int)) ws)
}
This resulted in the following error: 这导致以下错误:
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.
What I tried next (and worked), was: 我接下来尝试(并工作)的是:
readInts (s::String) = do {
let ws = (words s) in do
return (map (readMaybe::(String -> Maybe Int)) ws)
}
My question here is, words s
obviously is of type [String]
. 我的问题是, words s
显然是[String]
类型。 Why does the interpreter say it is a String
? 为什么解释器说它是String
? What am I not understanding about <-
operator? 我对<-
运算符不了解什么?
ws <- words s
, in the list monad, nondeterministically assigns one word from words s
to ws
; ws <- words s
,在单子列表中,不确定地将words s
一个单词分配给ws
; the remaining code simply works with that one word, and the return
function "magically" combines the results of working on all the words into the result list. 剩下的代码仅使用该单词, return
函数“神奇地”将所有单词的运算结果组合到结果列表中。
readInts s = do
ws <- words s -- ws represents *each* word in words s
return (readMaybe ws)
The do
notation is just syntactic sugar for using monadic bind
: do
表示法只是使用monadic bind
语法糖:
readInts s = words s >>= (\ws -> return (readMaybe ws))
Without using the Monad
instance for lists, you can use map
to apply the same function to each word. 在不使用Monad
实例进行列表的情况下,可以使用map
将相同的功能应用于每个单词。
readInts s = map readMaybe (words s)
let
, on the other hand, simply provides a name for a more complicated expression to be used in another expression. 另一方面, let
仅提供用于另一个表达式的更复杂表达式的名称。 It can be considered syntactic sugar for defining and immediately applying an anonymous function. 可以将其视为用于定义和立即应用匿名函数的语法糖。 That is, 那是,
let x = y + z in f x
is equivalent to 相当于
(\x -> f x) (y + z)
^ ^ ^
| | |
| | RHS of let binding
| part after "in"
LHS of let binding
A let
statement with multiple bindings is equivalent to nested let
statements: 一个let
与多个绑定语句相当于嵌套let
语句:
let x = y + z
a = b + c
in x + a
is equivalent to 相当于
let x = y + z
in let a = b + c
in x + a
which desugars to 哪个讨价还价
(\x -> (\a -> x + a)(b + c))(y + z)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.