Created by Dennis / @cdepillabout
class Add a where plus :: a -> a -> a instance Add Integer where plus x y = x + y instance Add Double where plus x y = x + y main = do print $ plus (5 :: Integer) 6 -- 11 is printed print $ plus (5.0 :: Double) 6.0 -- 11.0 is printed
definition of typeclass Add a
instance declaration
how to use
The a from type class Add is like a variable, it takes a variable Integer from the instance declaration. The Add Integer instance's plus method will have the following type: plus :: Integer -> Integer -> Integer
class Add a b where plus :: a -> b -> ??? instance Add Integer Double where plus x y = fromIntegral x + y instance Add Double Integer where plus x y = x + fromIntegral y
This is a little different from before. We are now passing two types to Add.When we want to write these instances of Add,what should we write for the type of the plus function?
We can't write the type of plus.Should the return type be a? b?
For the Add Integer Double instance,it should be b:plus :: a -> b -> b
For the Add Double Integer instance,it should be a:plus :: a -> b -> a
class Add a b where type SumTy a b = X plus :: a -> b -> SumTy a bX instance Add Integer Double where type SumTy Integer Double = Double plus x y = fromIntegral x + y instance Add Double Integer where type SumTy Double Integer = Double plus x y = x + fromIntegral y instance (Num a) => Add a a where type SumTy a a = a plus x y = x + y main = print $ plus (5 :: Integer) (6 :: Double)
First, lets look at the type class. What is the meaning of plus's SumTy?
Writing it like this should be a little easier to understand. SumTy a b = X. The return type of plus is X. In the instance declaration, the value of X is Double.
This is why they are called type-level functions.
class YesodAuth master where type AuthId master -- | Determine the ID associated with the set of credentials. getAuthId :: Creds master -> Maybe (AuthId master) instance YesodAuth BrowserId where type AuthId BrowserId = Text getAuthId = Just . credsIdent instance YesodAuth Auth2 where type AuthId BrowserId = String getAuthId = Just . credsIdent
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypFamilies #-}
class Add a b c | a b -> c where plus :: a -> b -> c instance Add Integer Double Double where plus x y = fromIntegral x + y instance Add Double Integer Double where plus x y = x + fromIntegral y instance (Num a) => Add a a a where plus x y = x + y main = print $ plus (5 :: Integer) (6 :: Double)
Similar to type families and can be used in some of the same places.