【发布时间】:2022-11-25 17:01:53
【问题描述】:
我正在努力精通 Monads 并编写了以下 Monads 和函数,其中我使用了 >>(在 apply-函数中),尽管它没有在 Monad 本身中声明。这怎么可能编译,据我了解 http://learnyouahaskell.com/a-fistful-of-monads#walk-the-line 需要在 Monad 的实例化中声明它,就像 Maybe Monad 的情况一样。
data Value =
NoneVal
| TrueVal | FalseVal
| IntVal Int
| StringVal String
| ListVal [Value]
deriving (Eq, Show, Read)
data RunErr = EBadV VName | EBadF FName | EBadA String
deriving (Eq, Show)
newtype CMonad a = CMonad {runCMonad :: Env -> (Either RunErr a, [String]) }
instance Monad CMonad where
return a = CMonad (\_ -> (Right a, []))
m >>= f = CMonad (\env ->
(Left a, strLst) -> (Left a, strLst)
(Right a, strLst) -> let (a', strLst') = runCMonad (f a) env in (a', strLst' ++ strLst))
output :: String -> CMonad ()
output s = CMonad(\env -> (Right (), [] ++ [s]))
apply :: FName -> [Value] -> CMonad Value
apply "print" [] = output "" >> return NoneVal
此外,我如何才能在运行应用程序时从控制台显示输出(打印)。目前我收到以下错误消息,尽管我的类型有 derive Show:
<interactive>:77:1: error:
* No instance for (Show (CMonad Value)) arising from a use of `print'
* In a stmt of an interactive GHCi command: print it
【问题讨论】:
-
对于最后一个问题,您没有为
CMonad派生任何实例,这是错误的来源。 GHC 无论如何都无法为函数类型派生那些实例;他们的要求没有多大意义。最后,>>=的定义至少有一个拼写错误——确保你检查它是否遵守法律。
标签: haskell types functional-programming monads