2014-02-28 81 views
1

我有一個類型爲T的定義如下,我想包裝一個整數在裏面。如何使「liftM2(+)(T 1)(T 2)」爲「新類型T = T Int」生成「T 3」

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' 

我知道我可以把它定義爲一個單子或者應用型,實際上是工作的好:

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 

考慮unnecessarity,我只是不想後添加一個多態參數a因爲T應該只包含整數。

我很好奇人們通常如何處理或規避這種不便。謝謝。

+0

我通常會添加類型參數。有時它開啓了我沒有想過的可能性。但這實際上取決於'T'的目的是什麼。 – luqui

回答

6

如何:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

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

演示了ghci:

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

我不覺得有必要爲使其作爲Monad一個實例,如果你只是想總結他們了。

相關問題