功能依赖/类型系列

通过函数依赖关系,我可以使用多参数类型类来约束类型类中的依赖参数的类型。 像这样:

{-# 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

一切都将完美运作。

> f (1 :: Int)
1
> f (1.9 :: Float)
1

但是,如果我尝试写类似的东西

instance F Double String where
  f = show

我会得到以下编译错误:

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'

有没有办法用类型系列来代替fundeps?


我想你想要这样的东西:

{-# 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

此示例不是直接使用类型族,而是使用相同标志激活的关联类型同义词。 这个想法相当简单。 我们定义了一个类型同义词,而不是明确地给第一个类型类型定义第二个参数,用适当的类型填充。

这也是我第一次使用关联类型同义词,但它似乎是一个非常酷的功能。


基本上不是,这实际上与功能依赖(或类型系列)无关。 你的班级定义有

class (Num a, Integral b) => F a b

它声明了必须有一个b的Integral实例。 一个String没有一个Integral实例,所以除非你定义,否则你不能有任何形式的F a String

-- String is a type synonym for [Char]
instance Integral [Char] where

我不知道这通常是明智的。 如果在您的系统中为Strings创建一个Integral实例是有意义的,那么您可能希望将一个新类型的wrapper放在String中并为其创建实例。

链接地址: http://www.djcxy.com/p/78241.html

上一篇: Functional Dependencies / Type Families

下一篇: UUImage imageWithContentsOfFile is nill