Hatena::Grouphaskell

[ pred x | x <- "Ibtlfmm!ojllj" ] RSSフィード

2008-02-17

deriving (Monad, Functor, ...)

6.8.2からの機能なのかどうか知らないが、deriving節にMonadと書いてもうまく動くことに気づいた。(data節では駄目で、newtypeのときのみ)

{-# OPTIONS -XGeneralizedNewtypeDeriving #-}

import Control.Monad.State

-- data S a だとエラーが起きる
newtype S a = S
  { runS :: State Int a
  } deriving (Monad, Functor, MonadState Int)

上のようなコードで、data S a = ...の時とnewtype S a = ...の時で異なるエラーが出る。

  • data S a = ...のとき
s.hs:5:0:
    Can't make a derived instance of `Monad S'
      (`Monad' is not a derivable class)
    In the data type declaration for `S'
s.hs:5:0:
    Can't make a derived instance of `Monad S'
      (`Monad' is not a derivable class
       Try -XGeneralizedNewtypeDeriving for GHC's newtype-deriving extension)
    In the newtype declaration for `S'

エラーメッセージに従ってファイルの先頭にOPTIONをつけてみるとエラーが消えた。MonadStateなどの複数型をとるクラスも大丈夫のようで、その場合は最後のところにはめ込まれてインスタンス化される。

*Main> :i S
newtype S a = S {runS :: State Int a}   -- Defined at a.hs:7:8
instance Monad S -- Defined at a.hs:7:8
instance Functor S -- Defined at a.hs:7:8
instance MonadState Int S -- Defined at a.hs:7:8

Abstract Data Typeと組み合わせて使うのに便利そうだ。