不明白Fay中的liftM2行为

时间:2013-09-06 22:29:10

标签: haskell fay

我有这个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的导入并粘贴liftF2,就像在Fay代码中一样,但它仍然可以正确地检查...在Fay中使用诸如liftMx这样的功能的任何选项,或者我是否丢失完全在这里的东西?

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

1 个答案:

答案 0 :(得分:3)

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