Tom*_*bus 1 monads haskell compiler-errors type-mismatch do-notation
我正在尝试实现一个将字符串转换为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)
}
Run Code Online (Sandbox Code Playgroud)
这导致以下错误:
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.
Run Code Online (Sandbox Code Playgroud)
我接下来(和工作)尝试的是:
readInts (s::String) = do {
let ws = (words s) in do
return (map (readMaybe::(String -> Maybe Int)) ws)
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,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)
Run Code Online (Sandbox Code Playgroud)
该do符号只是使用一元语法糖bind:
readInts s = words s >>= (\ws -> return (readMaybe ws))
Run Code Online (Sandbox Code Playgroud)
不使用Monad列表实例,您可以使用map相同的函数应用于每个单词.
readInts s = map readMaybe (words s)
Run Code Online (Sandbox Code Playgroud)
let另一方面,它只是为另一个表达式中使用的更复杂的表达式提供了一个名称.它可以被认为是用于定义和立即应用匿名函数的语法糖.那是,
let x = y + z in f x
Run Code Online (Sandbox Code Playgroud)
相当于
(\x -> f x) (y + z)
^ ^ ^
| | |
| | RHS of let binding
| part after "in"
LHS of let binding
Run Code Online (Sandbox Code Playgroud)
let具有多个绑定的语句等同于嵌套let语句:
let x = y + z
a = b + c
in x + a
Run Code Online (Sandbox Code Playgroud)
相当于
let x = y + z
in let a = b + c
in x + a
Run Code Online (Sandbox Code Playgroud)
不好意思
(\x -> (\a -> x + a)(b + c))(y + z)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |