IO Monad具有预期的输入值

时间:2018-07-30 19:01:18

标签: haskell

我是Haskell的新手,但我仍然不知道do monad是如何工作的。

例如,让我返回整数的do块被考虑为IO Integer

getNumber :: IO Integer -- A IO monad of type Integer
getNumber = return 100

但是例如,有一个返回Maybe User的do块,则do块的类型为Maybe User,但我期望IO (Maybe User)

persistUser :: IO (Maybe User)
persistUser = do return Just(User { userId = 100, userName = "Paul" })

相反,代码甚至没有编译。而且我找不到错误的编译器。

• Couldn't match type ‘a0 -> Maybe a0’ with ‘IO (Maybe User)’
  Expected type: User -> IO (Maybe User)
    Actual type: User -> a0 -> Maybe a0
• The function ‘return’ is applied to two arguments,
  but its type ‘(a0 -> Maybe a0) -> User -> a0 -> Maybe a0’
  has only three
  In a stmt of a 'do' block:
    return Just (User {userId = 100, userName = "Paul"})
  In the expression:
    do { return Just (User {userId = 100, userName = "Paul"}) }

似乎期望用户作为输入,但甚至添加签名

User -> IO (Maybe User)User IO (Maybe User)不起作用。

也许我误解了文档中的内容。对此进行一些澄清将是很棒的!

致谢。

2 个答案:

答案 0 :(得分:4)

您只需要更多的括号即可:

do return (Just(User { userId = 100, userName = "Paul" }))

与许多语言不同,return在Haskell中不是一个特殊的关键字,而是一个库函数,因此不能像在其他语言(如C或Python)中那样省略参数的括号。

答案 1 :(得分:1)

除了丹尼尔·瓦格纳(Daniel Wagner)的答案,您还可以使用class Item { constructor(type) { this.constructor.counter = ((this.constructor.hasOwnProperty('counter') && this.constructor.counter) || 0) + 1; this.type = type || "item"; this._id = this.type + "_" + this.constructor.counter; console.log(this.id); } get id() { return this._id; } } class SubItem extends Item { constructor() { super("sub_item"); } } var test1 = new Item(); // <- "item_1" var test2 = new Item(); // <- "item_2" var test3 = new Item(); // <- "item_3" var test4 = new Item(); // <- "item_4" var test5 = new SubItem(); // <- "sub_item_5" var test6 = new SubItem(); // <- "sub_item_6" var test7 = new Item(); // <- "item_5" var test8 = new Item(); // <- "item_6"运算符来组成.return

Just

getNumber = return . Just $ User { userId = 100, userName = "Paul" } 运算符是低优先级函数应用程序运算符,可用于减少括号。以上等同于$。 (实际上,由于return . Just (User { userId = 100, userName = "Paul" })实例中的return = Just,您还可以编写Maybe。)

无论如何,这里return . return $ User { userId = 100, userName = "Paul" }是不必要的,因为关键字后面只有一个“语句”。