我有一个类型T
定义如下,我想在其中包装一个整数。
newtype T = T Int
-- liftM2 (+) (T 1) (T 2) -- error: `T' is not an instance of Monad
现在,如果我想在包装器中包装一个操作值并返回类似于liftM*
所做的结果,就像上面的代码所示,但它不起作用。我希望一组函数的行为类似myLiftT2
,但更常用。
myLiftT2 :: (Int -> Int -> Int) -> T -> T -> T
myLiftT2 f (T a) (T b) = T $ f a b
myLiftT2 (+) (T 1) (T 2) -- `T 3'
我知道我可以将它定义为Monad或Applicative并且实际上效果很好:
newtype T a = T a
instance Monad T where
(T a) >>= f = f a
return = T
liftM2 (+) (T 1) (T 2) -- produces `(T 3)' as expect
考虑到不必要性,我只是不想在类型之后添加多态性参数a
,因为T
应该只包装整数。
我很好奇人们通常如何处理或避免这种不便。感谢。
答案 0 :(得分:6)
这个怎么样:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype T = T Int deriving (Show, Eq, Num)
ghci中的演示:
ghci> (T 1) + (T 2)
T 3
如果您只是想总结一下,我觉得不需要将其作为Monad
的实例。