如何在Haskell中将其自定义monad的函子定义作为基础

时间:2018-09-26 10:14:06

标签: haskell

我在Haskell中定义了一个将状态和错误处理结合在一起的自定义monad,如下所示:

[user@host h2]$ java -cp h2*.jar org.h2.tools.Shell -user sa -password sa -url jdbc:h2:tcp://localhost/~/mydb
Welcome to H2 Shell 1.4.197 (2018-03-18)
...
sql> CREATE ALIAS IS_PRIME FOR "acme.Function.isPrime";
(Update count: 0, 9 ms)
sql> CALL IS_PRIME(5);
PUBLIC.IS_PRIME(5)
TRUE
(1 row, 31 ms)

代码可以很好地编译,但是在monad中import Control.Applicative import Control.Monad data Result a e = Ok a | Error e newtype StateError s e a = StateError { runStateError :: s -> (Result a e, s) } instance Functor (StateError s e) where fmap f m = StateError $ \s -> case runStateError m s of (Ok x, s1) -> (Ok (f x), s1) (Error e, s1) -> (Error e, s1) instance Applicative (StateError s e) where pure x = StateError $ \s -> (Ok x, s) a <*> b = ap a b instance Monad (StateError s e) where return = pure m >>= f = StateError $ \s -> case runStateError m s of (Ok x, s1) -> runStateError (f x) s1 (Error e, s1) -> (Error e, s1) get = StateError $ \s -> ((Ok s), s) put s = StateError $ \_ -> ((Ok ()), s) main = return () fmap绑定操作符的定义之间似乎存在一些冗余。

如何重新定义绑定运算符以利用函子定义?

如果这不可能,为什么我必须为我的自定义monad定义函子?
如果我不打算在任何地方使用>>=,这似乎没用。

谢谢

注意:我知道monad转换器存在,也许它们是将现有状态和错误monad合并为一个的正确方法,但是出于学习的原因,我更喜欢这种方法(我对monad的经验很少)。

注意:此问题是我其他问题How to create a monad that combines state and error in Haskell的后续内容。

0 个答案:

没有答案