我把 Monad、ReaderT 弄得一团糟……来执行“简单?” 行为。
我想将测试功能散布到Maybe
转换(Maybe
或另一个个性化的单子)中。
确切地说,我想避免t
调用,创建某种单子(我认为是单子)
doCalculus :: (Int -> Bool) -> Int -> Maybe Int
doCalculus f a = do
b <- t $ a + 1
c <- t $ 2 * b
d <- t $ a + b + c
return d
where t = if f n then Just n else Nothing
例子
test :: Int -> Bool
test n = not (n `elem` [3, 7, 9])
*Main> doCalculus test 2
Nothing
*Main> doCalculus test 3
Just 15
*Main>
我正在尝试做一些单子喜欢ReaderT
执行一些喜欢
runMaybeTest doCalculus test
用作
doCalculus :: Int -> Maybe' Int
doCalculus a = do
b <- a + 1
c <- 2 * b
d <- a + b + c
return d
perform = runMaybe' doCalculus test
但我不能。
(当然,Int
类型将泛型为 monad)
谢谢你的任何提示!
=== 更新 1 ===
我能做到!:) ...但不实用(我认为):(
我改编了一篇精彩的Eric Kidd 帖子
import Prelude hiding (Just, Nothing, return, (>>=))
class Tester a where
test :: a -> Bool
test _ = True
data MMaybe a = Nothing | Just a deriving (Eq, Show)
class Monad1 m a where
return :: a -> m a
fail :: String -> m a
class (Monad1 m a, Monad1 m b) => Monad2 m a b where
(>>=) :: m a -> (a -> m b) -> m b
instance (Tester a) => Monad1 MMaybe a where
return = Just
fail _ = Nothing
instance (Tester a, Tester b) => Monad2 MMaybe a b where
Nothing >>= _ = Nothing
(Just x) >>= f = if test x then f x else Nothing
instance Tester Int where
test n = not $ n `mod` 2 == 0 && n `mod` 3 == 0
test1 :: Int -> MMaybe Int
test1 n =
return n >>= \a ->
return (a + 3) >>= \b ->
return (a + b)
test2 = map test1 [1..20]
可能的(重要)问题是:
- 是可用的单子吗?
- do符号在哪里?
- 仅适用于将测试功能定义为唯一类型(新测试功能需要新类型)
但我可以将测试函数包装成伪单子......(它的东西)