【发布时间】:2019-03-01 14:02:51
【问题描述】:
我不明白为什么这个代码示例不起作用,而在 RWH 书中它起作用了:
module Monads where
import Data.Maybe
import Control.Monad
amap=[("a",1),("bb",2)]
bmap=[(1,100),(2,200)]
final=[(100,1000),(200,2000)]
f::String->IO (Maybe Int)
f par=do
a<-lookup par amap
b<-lookup a bmap
lookup b final
它不起作用,我不明白它是如何工作的,因为最后一行返回 Maybe something 而不是 IO something。
我还尝试将最后一行更改为 :return (lookup b final)
我的推理应该是完美的(查找返回 Maybe Int 然后用 return 包装它)
使用return时出现以下错误
* Couldn't match type `Maybe' with `IO'
Expected type: IO Integer
Actual type: Maybe Integer
* In a stmt of a 'do' block: b <- lookup a bmap
In the expression:
do a <- lookup par amap
b <- lookup a bmap
return (lookup b final)
In an equation for `f':
f par
= do a <- lookup par amap
b <- lookup a bmap
return (lookup b final)
|
11 | b<-lookup a bmap
| ^^^^^^^^^^^^^
【问题讨论】:
-
do块指的是Maybe,而不是IO。看起来整个东西应该是f par = return $ do ...,或者您可以将类型更改为f::String->Maybe Int。 -
你是对的,这永远不会起作用(如果返回类型是
Maybe Int,它会起作用)。但是我在您链接到的章节中的任何地方都没有看到该代码 sn-p 。 (实际上我不久前经历了 RWH 的大部分内容——它已经过时了,而且他们使用的许多模块似乎不再使用相同的 API 存在——但我不记得这样的事情了。) -
您的代码中没有任何内容表明
f必须返回IO值。 -
不,
do适用于 any monad。 -
@RobinZigmond 这就是我的意思;类型签名对返回类型施加了一个外部约束,其参数或它所操作的列表并未建议。