xafizoff
xafizoff

Reputation: 407

Constraint on associated type in Haskell

I would like to associate my typeclass with the type, which is an instance of the certain typeclass (Show for example).

Solution with the fundeps:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class (Show msg) => Handler msg h | h -> msg where
   handle :: h -> msg -> String

So I can implement the Handler, which will handle only data of associated type.

data IntHandler = IntHandler
instance Handler Int IntHandler where -- OK.
   handle _ x = show x    data Foo = Foo

handle IntHandler 1   -- OK.
handle IntHandler "1" -- Fail.

data Foo = Foo
data FooHandler = FooHandler
instance Handler Foo FooHandler where  -- Fails to typecheck, Foo is not an instance of Show
   handle _ _ = "failed"

The question: how to achieve the same functionality with the type families?

Let's try and declare the Handler' class and its implementation for IntHandler' type:

{-# LANGUAGE TypeFamilies #-}
class Handler' h where
    type Msg h
    handle' :: h -> Msg h -> String

data IntHandler' = IntHandler'
instance Handler' IntHandler' where
    type Msg IntHandler' = Int
    handle' _ x = show x

Good, this type checks. Now let's create implementation for the Foo type:

data Foo = Foo
data FooHandler' = FooHandler'
instance Handler' FooHandler where
    type Msg FooHanler' = Foo
    handle' _ _ = "this won't fail"

But it also typechecks, but I want to prevent it to type check. So, how to constrain the result of the type function Msg?

Upvotes: 3

Views: 746

Answers (1)

xafizoff
xafizoff

Reputation: 407

As @Carl is pointed out, it's pretty obvious:

class (Show (Msg h)) => Handler h where

It was my silly mistake... Just had to enable FlexibleContexts.

Upvotes: 3

Related Questions