封闭式家庭和奇怪的功能类型 [英] Closed type families and strange function types
问题描述
对不起,我无法想象这个问题有更好的标题,所以请先阅读。想象一下,我们有一个封闭类型的家族,它将每个类型映射到相应的 Maybe
,除了maybes自己:
type family Family x其中
Family(Maybe x)=也许x
Family x =也许x
我们甚至可以使用该类型系列声明一个函数:
doMagic :: a - >家庭a
doMagic =未定义
exampleA = doMagic $ Just()
exampleB = doMagic $()
在GHCi中使用它可以显示评估此函数应用程序的类型:
*奇怪> :t exampleA
exampleA :: Maybe()
* Strange> :t exampleB
exampleB :: Maybe()
问题是如果有可能提供除 undefined
之外的 doMagic
函数的任何实现。举个例子说,我想将每个值都包含到 Just 构造函数中,但Maybes应该保持不变,除此之外我怎么做?我试过使用类型类,但是如果没有使用封闭类型的家族,没有写出doMagic函数的可编译签名,有人可以帮我吗? 解决方案
您可以使用另一个封闭类型族来区分 Maybe x
from x
,然后您可以使用另一个类型类型为这两种情况分别提供 doMagic
的实现。 Quick and dirty version:
{ - #LANGUAGE TypeFamilies,MultiParamTypeClasses,
FlexibleInstances,UndecidableInstances,ScopedTypeVariables# - }
类型家庭x其中
家庭(也许x)=也许x
家庭x =也许x
数据真
数据假
类型系列IsMaybe x其中
IsMaybe(也许x)=真
IsMaybe x =假
类DoMagic a其中
doMagic :: a - >家庭
实例(DoMagic'(IsMaybe a)a(Family a))=> DoMagic a
doMagic = doMagic'(undefined :: IsMaybe a)
class DoMagic'i a r where
doMagic':: i - > a - > r
实例DoMagic'True(也许a)(也许a)其中
doMagic'_ = id
实例DoMagic'假a(也许a)其中
doMagic'_ = Just
exampleA = doMagic $ Just()
exampleB = doMagic $()
Sorry, I couldn't imagine any better title for the question, so please read ahead. Imagine that we have a closed type family that maps every type to it's corresponding Maybe
except maybes themselves:
type family Family x where
Family (Maybe x) = Maybe x
Family x = Maybe x
We can even declare a function using that type family:
doMagic :: a -> Family a
doMagic = undefined
exampleA = doMagic $ Just ()
exampleB = doMagic $ ()
Playing with it in GHCi shows that it is ok to evaluate the type of this function application:
*Strange> :t exampleA
exampleA :: Maybe ()
*Strange> :t exampleB
exampleB :: Maybe ()
The question is if it is possible to provide any implementation of the doMagic
function except undefined
? Let's for example say that I would like to wrap every value into a Just
constructor, except Maybes which should remain intact, how could I do that? I tried using typeclasses, but failed to write a compileable signature for doMagic function if not using closed type families, could somebody please help me?
You can use another closed type family to distinguish Maybe x
from x
and then you can use another typeclass to provide separate implementations of doMagic
for these two cases. Quick and dirty version:
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses,
FlexibleInstances, UndecidableInstances, ScopedTypeVariables #-}
type family Family x where
Family (Maybe x) = Maybe x
Family x = Maybe x
data True
data False
type family IsMaybe x where
IsMaybe (Maybe x) = True
IsMaybe x = False
class DoMagic a where
doMagic :: a -> Family a
instance (DoMagic' (IsMaybe a) a (Family a)) => DoMagic a where
doMagic = doMagic' (undefined :: IsMaybe a)
class DoMagic' i a r where
doMagic' :: i -> a -> r
instance DoMagic' True (Maybe a) (Maybe a) where
doMagic' _ = id
instance DoMagic' False a (Maybe a) where
doMagic' _ = Just
exampleA = doMagic $ Just ()
exampleB = doMagic $ ()
这篇关于封闭式家庭和奇怪的功能类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!