Contact/support | Changelog

Type class canonicity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{-# LANGUAGE RankNTypes, GeneralizedNewtypeDeriving #-}

module Foo where

class    IsInt a   where cast :: f Int -> f a
instance IsInt Int where cast = id

class    C a      where wat :: a
instance C Int    where wat = 1
instance C NotInt where wat = 2

newtype Foo a = Foo { unFoo :: forall r. (C a => a -> r) -> r }

newtype NotInt = NI Int deriving (Num, Show, IsInt)

-- errors; Foo is not a functor
-- mapFoo :: (a -> b) -> Foo a -> Foo b
-- mapFoo f (Foo e) = Foo $ \k -> e (k . f)

runFoo :: Foo a -> a
runFoo (Foo e) = e (\_ -> wat)

mkFoo :: C a => a -> Foo a
mkFoo x = Foo $ \k -> k x

zig = runFoo $ mkFoo 0 :: Int            -- 1
zag = runFoo $ mkFoo 0 :: NotInt         -- NI 2
zug = runFoo . cast $ mkFoo 0 :: NotInt  -- NI 1
21:21: Warning: Use const
Found:
\ _ -> wat
Why not:
const wat