Functional Dependencies / Type Families
With functional dependencies I can constrain type of dependent parameter in a type class using multi-parameter type classes. Just like this:
{-# LANGUAGE FunctionalDependencies, MultiParamTypeClasses,TypeSynonymInstances #-}
class (Num a, Integral b) => F a b | a -> b where
f :: a -> b
instance F Int Int where
f = id
instance F Float Integer where
f = truncate
And everything'll work perfectly.
> f (1 :: Int)
1
> f (1.9 :: Float)
1
But if I try to write something like
instance F Double String where
f = show
I'll get the following compilation error:
No instance for (Integral String)
arising from the superclasses of an instance declaration
Possible fix: add an instance declaration for (Integral String)
In the instance declaration for `F Double String'
Is there a way to approach this with type families instead of fundeps?
I guess you want to have something like this:
{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
class Num a => G a where
type B a
g :: (Integral (B a)) => a -> B a
instance G Int where
type B Int = Int
g = id
instance G Float where
type B Float = Integer
g = truncate
This example is not directly using a type family, but an associated type synonym, which is activated by the same flag. The idea is fairly easy. Instead of explicit giving a second parameter to the typeclass, we define a type synonym, that is filled in with the appropriate type.
This is also my first time to use associated type synonyms, but it seems to be a quite cool feature.
Basically not, and this actually has nothing to do with functional dependencies (or type families). Your class definition has
class (Num a, Integral b) => F a b
which declares that there must be an Integral instance for b
. A String
doesn't have an Integral instance, so you can't have anything of the form F a String
unless you define
-- String is a type synonym for [Char]
instance Integral [Char] where
I don't know that this would be sensible in general. If it would make sense to create an Integral instance for Strings in your system, you would probably want to put a newtype wrapper around String and create the instance for that instead.
链接地址: http://www.djcxy.com/p/78242.html上一篇: 类型家庭类型的黑客
下一篇: 功能依赖/类型系列