出力する型を指定することによって違う型を返す関数

return や pure は出力する型を指定することによって違う型を返します。

ghci> (return 123)::IO Int     -- > 123
ghci> (return 123)::[Int]      -- > [123]
ghci> (return 123)::Maybe Int  -- > Just 123

ghci> :m + Control.Applicative
ghci> (pure 123)::Maybe Int    -- > Just 123
ghci> (pure 123)::[Integer]    -- > [123]

それと同じように出力する型を指定することによって違う型を返す関数を作れないかと思ってやってみました。

data I = I Integer deriving (Eq, Show)
data S = S String  deriving (Eq, Show)
data Hoge = Hoge String deriving Show

-- Calc クラス
class Calc b where
     add :: Integer -> Integer -> b

-- I に対するCalc クラスのインスタンス
instance Calc I where
     add a b = I (a + b)

-- S に対するCalc クラスのインスタンス
instance Calc S where
     add a b = S (show $ a + b)

-- Hoge に対するCalc クラスのインスタンス
instance Calc Hoge where
     add a b = Hoge ("HogeHoge:" ++ show (a + b))

-- 関数、引数は同じであっても、返すが値が指定した型に変わる。
ghci> (add 123 456)::I    -- > I 579
ghci> (add 123 456)::S    -- > S "579"
ghci> (add 123 456)::Hoge -- > Hoge "HogeHoge:579"

MonadPlus:返す値の型をリスト、Maybeのどちらかに指定できる:リストとMaybeま似ている。空のリストがNothing、1個目のリストをJustと考え、あとは無視するとか。

2011/12/22 同じような記事発見。返り値の型を指定する必要のある関数を定義してみる