Gus*_*ust 2 monads haskell types
老实说,我觉得这必须有一个傻瓜的地方,但我找不到它 甚至 后 搜索 。
假设我有以下代码来简单地从用户那里读取一个 double 并将其回显:
import qualified Control.Monad.Except as E
import Text.Read(readMaybe)
data Error = ParseError String
| Default String deriving (Show)
type ThrowsError = Either Error
main = do
putStrLn "Enter your number: "
val <- getDouble
print val
parseString :: String -> ThrowsError Double
parseString val = maybe (E.throwError $ ParseError val) return
(readMaybe val :: Maybe Double)
getDouble :: ThrowsError Double
getDouble = getLine >>= parseString
Run Code Online (Sandbox Code Playgroud)
这在两个地方中断:
在main,putStrLn是类型IO Double但是getDouble是类型ThrowsError Double。
在getDouble,getLine是类型IO Double但parseString返回IO Double。
本质上,我希望能够从IOmonad 中提取值,对其进行计算,然后将其放回适当的 monad 中。但是,绑定函数似乎期望输入和输出具有相同的 monad 类型,所以我想要做的不起作用。
有什么办法呢?
你不需要任何变压器。 parseString是一个纯函数,因此要将其应用于您使用的 monadic 操作fmap(又名(<$>)),而不是(>>=)像您那样。
getDouble :: IO (ThrowsError Double)
getDouble = parseString <$> getLine
Run Code Online (Sandbox Code Playgroud)
您将使用(>>=)ifparseString返回一个IO something.