如何制作" liftM2(+)(T 1)(T 2)"致力于生产" T 3" for" newtype T = T Int"

时间:2014-02-28 20:58:16

标签: haskell monads applicative

我有一个类型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应该只包装整数。

我很好奇人们通常如何处理或避免这种不便。感谢。

1 个答案:

答案 0 :(得分:6)

这个怎么样:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype T  = T Int deriving (Show, Eq, Num)

ghci中的演示:

ghci> (T 1) + (T 2)
T 3

如果您只是想总结一下,我觉得不需要将其作为Monad的实例。