Last active
April 20, 2021 09:14
-
-
Save ongyiren1994/30d406f5b3ec936b2f8ff4b765620a15 to your computer and use it in GitHub Desktop.
A Random Tour of Typeclass in Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- code examples from https://fpbyintuition.medium.com/ | |
{-# LANGUAGE ConstraintKinds #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE FunctionalDependencies #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE NoStarIsType #-} | |
{-# LANGUAGE KindSignatures #-} | |
import GHC.Exts (Constraint) | |
import GHC.Types | |
import Prelude hiding (Monad, return, (>>=)) | |
class Monad m where | |
(>>=) :: m a -> (a -> m b) -> m b | |
return :: a -> m a | |
instance Monad Maybe where | |
Nothing >>= f = Nothing | |
(Just x) >>= f = f x | |
return = Just | |
instance Monad (Either e) where | |
return = Right | |
Left l >>= _ = Left l | |
Right r >>= k = k r | |
f :: (Monad m) => String -> m [Char] | |
f x = return x | |
g :: a -> Maybe a | |
g x = Just x >>= return | |
g' :: (Monad m, m ~ Maybe) => a -> m a | |
g' x = Just x >>= return | |
-- > :t return | |
-- return :: Monad m => a -> m a | |
-- | |
-- > :t return @Maybe | |
-- return @Maybe :: a -> Maybe a | |
-- | |
-- > :t return @Maybe "hello" | |
-- return @Maybe "hello" :: Maybe [Char] | |
-- | |
-- > return @Maybe "hello" | |
-- Just "hello" | |
class Id m where | |
identity :: m -> m | |
instance Id m where | |
identity m = m | |
h :: a -> a | |
h x = identity x | |
-- instance Id Bool where | |
-- identity m = not m | |
-- | |
-- instance {-# OVERLAPPING #-} Id Bool where | |
-- identity a = not a | |
-- class Transform a b where | |
-- transform :: a -> b | |
-- instance Transform String (Maybe Bool) where | |
-- transform "True" = Just True | |
-- transform "False" = Just False | |
-- transform _ = Nothing | |
-- instance Transform String (Maybe Int) where | |
-- transform "zero" = Just 0 | |
-- transform _ = Nothing | |
-- > transform "1" :: Maybe Bool | |
-- Nothing | |
-- > transform @String @(Maybe Bool) "1" | |
-- Nothing | |
class Transform a b | a -> b where | |
transform :: a -> b | |
instance Transform String (Maybe Bool) where | |
transform "True" = Just True | |
transform "False" = Just False | |
transform _ = Nothing | |
instance Transform Bool String where | |
transform True = "True" | |
transform False = "False" | |
-- | |
class Transform' a where | |
type F a | |
transform' :: a -> F a | |
instance Transform' String where | |
type F String = Maybe Bool | |
-- transform' :: String -> Maybe Bool | |
-- we substitute (F String) with (Maybe Bool) | |
transform' "True" = Just True | |
transform' "False" = Just False | |
transform' _ = Nothing | |
instance Transform' Bool where | |
type F Bool = String | |
-- transform' :: Bool -> String | |
-- we substitute (F Bool) with (String) | |
transform' True = "True" | |
transform' False = "False" | |
class Memo a where | |
data Table a :: Type -> Type | |
toTable :: (a -> w) -> Table a w | |
fromTable :: Table a w -> (a -> w) | |
instance Memo Bool where | |
data Table Bool w = TBool w w | |
toTable f = TBool (f True) (f False) | |
fromTable (TBool x y) b = if b then x else y | |
-- > :t TBool | |
-- w -> w -> Table Bool w | |
class Graph g where | |
type Vertex g | |
data Edge g | |
src, tgt :: Edge g -> Vertex g | |
outEdges :: g -> Vertex g -> [Edge g] | |
class Trivial a -- No further definition | |
instance Trivial a -- No futher implementation | |
-- > :k Trivial (Either) -- the kind of Trivial is (Type -> Type -> Type) -> Constraint | |
-- Constraint | |
-- > :k Trivial (Either Int) -- the kind of Trivial is (Type -> Type) -> Constraint | |
-- Constraint | |
-- > :k Trivial (Either Int Int) -- the kind of Trivial is (Type -> Constraint | |
-- Constraint | |
data Dict (p :: Constraint) where | |
Dict :: p => Dict p | |
-- > :t Dict @(Show Int) | |
-- Dict (Show Int) | |
-- > :t Dict @(Eq Int) | |
-- Dict (Eq Int) | |
-- > :t Dict @(Trivial Int) -- Let's not forget our trivial typeclass | |
-- Dict (Trivial Int) | |
type Cons a = (Eq a, Ord a) | |
-- > :k Cons Int | |
-- Constraint | |
data Direction = North | West | South | East | |
deriving (Ord, Eq) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment