【发布时间】:2013-02-21 23:58:45
【问题描述】:
我正在和 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 post
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 表示法在哪里?
- 仅适用于将测试函数定义为唯一类型(新测试函数需要新类型)
但我可以将测试函数包装到伪单子中......(它的东西)
【问题讨论】:
-
我不清楚你到底想做什么(但这不一定是你的错)。如果您想编写添加了“Maybe”上下文的函数,请使用 Maybe monad 和使用 bind >>= 运算符的链函数?
-
如果这听起来像你想要做的,我会提交一个完整的答案并尝试提供帮助。
-
我认为您无法以任何重要的方式摆脱
t。你将如何将表达式提升到 monad 中,以及如何界定应该执行测试的位置? -
在我看来,您对 Haskell 的看法是错误的,忽略了它的懒惰。
-
是的@JohnL,这是个问题,如果我将“测试”函数(静态,“恒定地”,内联,...)写入
Maybemonad 没有问题。如何参数化该测试功能?谢谢!
标签: haskell monad-transformers