【问题标题】:Haskell : Float to IO FloatHaskell:浮点数到 IO 浮点数
【发布时间】:2017-11-08 20:43:45
【问题描述】:

我有这个函数的类型问题

type Store = [(String, Float)]
evalParser :: String -> Store -> Float -- Boring function who returns a Float

programme :: Store -> IO()
programme store = do
    putStr "@EvmInteractif:$> "
    instruction <- getLine
    putStrLn (show instruction)

    if (estCommande (instruction) == True) then
        do
            res <- evalParser instruction store
            putStrLn "TODO: execution de la commande"
            programme store

在 res 的矫揉造作中,我遇到了这个错误:

无法匹配预期类型 IO Float' with actual typeFloat' 在“evalParser”调用的返回类型中 在“do”块的 stmt 中:v

谁能告诉我正确的语法吗? 谢谢

【问题讨论】:

  • 使用let res = ... 而不是res &lt;- ...
  • estCommande (instruction) == True ~ estCommande (instruction)
  • 有点半开玩笑的解决方案:因为res 没有在任何地方使用,您可以删除有问题的行。但只是有点开玩笑,因为这里有一个教训,即:我怀疑你相信仅仅调用evalParser 会“做某事”,但它不会。这闻起来像是你犯了一个错误。例如也许evalParser 应该返回一个更新的存储以在以后对programme 的递归调用中使用,或者您可能打算打印结果,或者两者兼而有之。或者也许你在原版中做了这些,但把它们删掉了做一个最小的例子,在这种情况下,荣誉!

标签: haskell io


【解决方案1】:

evalParser 是纯的,你不需要使用 do 表示法来调用它。要修复它,您可以将其包装在 return 中以将其粘贴在 IO Monad 中:

res <- return $ evalParser instruction store

为了完全避免包装/展开,请不要从一开始就将其视为不纯的值:

let res = evalParser instruction store

【讨论】:

  • 既然“箭头”是一个有自己语法的概念,也许我们应该坚持称它为“do notation”或“monadic bind”以避免以后造成混淆。
  • @ThomasM.DuBuisson 我最初有“do notation”,但对我来说听起来不合适。我已经有几年没有写过 Haskell 了,所以我忘记了一些术语。我会改回来的。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
相关资源
最近更新 更多