封闭式家庭和奇怪的功能类型 [英] Closed type families and strange function types

查看:199
本文介绍了封闭式家庭和奇怪的功能类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,我无法想象这个问题有更好的标题,所以请先阅读。想象一下,我们有一个封闭类型的家族,它将每个类型映射到相应的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆