重叠/不连续的封闭类型族
我一直在玩一些封闭类型的家庭,但是我总觉得事物往往不适用于Num
而没有指定类型。
这是一个例子。
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
module Main where
import Data.Typeable
type family UnMaybed a where
UnMaybed (Maybe a) = a
UnMaybed a = a
class UnMaybe x where
unMaybe :: x -> UnMaybed x
instance UnMaybe (Maybe a) where
unMaybe (Just a) = a
instance (UnMaybed a ~ a) => UnMaybe a where
unMaybe a = a
main = do
print $ unMaybe 'c'
print $ unMaybe (1::Int)
print $ unMaybe (Just 1)
print $ unMaybe 1 -- this line does not compile
除最后一行之外的所有内容都将被编译
../Example.hs:23:17:
Occurs check: cannot construct the infinite type: s0 ~ UnMaybed s0
The type variable ‘s0’ is ambiguous
In the second argument of ‘($)’, namely ‘unMaybe 1’
In a stmt of a 'do' block: print $ unMaybe 1
现在我知道这是因为数字是多态的,并且( Maybe a
)可能是Num
一个实例。 我认为对于正常重叠的类型类,这个困境可以通过使用IncoherentInstances
PRAGMA来解决。 无论如何,我想问问是否有办法在类型家庭中完成这项工作?
我也想过在UnMaybed
明确指定Num
type family UnMaybed a where
unMaybed (Num a => a) = a
UnMaybed (Maybe a) = a
UnMaybed a = a
这编译,但我认为第一个案件永远不会匹配这可能是一个错误。
回答:http://www.haskell.org/pipermail/haskell-cafe/2014-March/113153.html
这是封闭式家庭的限制,但限制是有充分理由的。
IncoherentInstances威胁类型实例的一致性,这意味着即使对于相同的<<some type>>
,在不同地方可能会以不同的方式实现一个约束UnMaybe <<some type>>
<<some type>>
。 但是,类型实例选择纯粹是一种运行时行为效应。 选择不同的实例不会影响程序中的类型。
另一方面,类型家族直接影响类型。 允许像IncoherentInstances工作方式一样的不连贯性可以用来实现unsafeCoerce。
没有类型签名,没有太多的方法。 (一种可能性是基本上使用RebindableSyntax来禁用数字重载,但这是一个大锤子。)
最后一个例子(使用UnMaybed(Num a => a))甚至编译的事实是一个很快就会出现的错误。
修订
我发现你可以实际实现这个功能,而不需要像下面这样输入系列。
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
class UnMaybe x y where
unMaybe :: x -> y
instance (a~a') => UnMaybe (Maybe a) a' where
unMaybe (Just a) = a
instance (a~a') => UnMaybe a a' where
unMaybe a = a
请注意,由于等式约束,您仍然需要类型族扩展。
链接地址: http://www.djcxy.com/p/78247.html