typeでは型引数を省略しないと高階型クラスインスタンスにできない

class Foo (a :: * -> *)

 のように、高階型に実装されることを要求する型クラスに対して

data Bar a = Bar Int a
type Baz a b = Either (Bar a) b

のようにすると

class Foo (Baz a)

できなくなってしまって

type Baz a = Either (Bar a)

のようにするとできるという感じです。


{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}

import Control.Eff (Eff, (:>))
import Control.Eff.Exception (Fail, throwExc)
import Control.Monad.Fail (MonadFail(..))
import Data.Void (Void)
import Prelude hiding (fail)

-- `a`をつけると
type Mine a = Eff (Fail :> Void) a

-- compile error !
instance MonadFail Mine where
  fail _ = throwExc ()

main :: IO ()
main = return ()
Test.hs|13 col 10| error:
     • The type synonym ‘Mine’ should have 1 argument, but has been given none
     • In the instance declaration for ‘MonadFail Mine’

Mineの型引数aを消してみるとコンパイルが通る。

type Mine = Eff (Fail :> Void)

つまりモナドスタックのような構造のうち部分は、このような

筆者プロフィール

my-latest-logo

aiya000(あいや)

せつラボ 〜圏論の基本〜」 「せつラボ2~雲と天使と関手圏~」 「矢澤にこ先輩といっしょに代数!」を書いています!

強い静的型付けとテストを用いて、バグを防ぐのが好き。Haskell・TypeScript。