我有这个 Haskell 代码,它的行为符合预期:

import Control.Monad

getVal1 :: Maybe String
getVal1 = Just "hello"

getVal2 :: Maybe String
getVal2 = Just "World"

main = process >>= putStrLn

process :: IO String
process = case liftM2 operation getVal1 getVal2 of
    Nothing -> error "can't run operation, one of the params is Nothing"
    Just result -> result

operation :: String -> String -> IO String
operation a b = return $ a ++ b

但是,当转换为 Fay 时,它不会进行类型检查:
{-# LANGUAGE NoImplicitPrelude, EmptyDataDecls #-}

import Prelude
import FFI

liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }

getVal1 :: Maybe String
getVal1 = Just "hello"

getVal2 :: Maybe String
getVal2 = Just "World"

main = process >>= putStrLn

process :: Fay String
process = case liftM2 operation getVal1 getVal2 of
    Nothing -> error "can't run operation, one of the params is Nothing"
    Just result -> result

operation :: String -> String -> Fay String
operation a b = return $ a ++ b

编译错误是:
fay: ghc:
TestFay.hs:17:33:
    Couldn't match expected type `Fay String'
                with actual type `Maybe String'
    In the second argument of `liftM2', namely `getVal1'
    In the expression: liftM2 operation getVal1 getVal2
    In the expression:
      case liftM2 operation getVal1 getVal2 of {
        Nothing
          -> error "can't run operation, one of the params is Nothing"

我并没有完全关注这里的问题。实际上,我什至尝试在 GHC 代码中删除 Control.Monad 的导入,并像 Fay 代码中一样粘贴 LiftM2,但它仍然可以正确进行类型检查......在 Fay 中使用诸如liftMx 等功能的任何选项,或者我是否缺少东西完全在这里?

这是 Fay 0.16.0.3 ... 也许我应该尝试升级到 0.17?

最佳答案

我怀疑 Fay 中的 do 符号仅适用于 Fay monad,因为 AFAIK Fay 不支持类型类。查看 the Fay Prelude ,我看到 (>>=)return 是单态的,专门用于 Fay monad。

关于haskell - 不理解 Fay 中的这种liftM2行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18667530/

10-12 20:30