我有一个类型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
应该只包装整数。
我很好奇人们通常是如何处理或规避这种不便的。谢谢
这个怎么样:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype T = T Int deriving (Show, Eq, Num)
ghci:演示
ghci> (T 1) + (T 2)
T 3
如果你只想总结一下,我觉得没有必要把它作为Monad
的一个例子。