封闭型系列和奇怪的功能类型

Ant*_*ton 8 haskell type-families

对不起,我无法想象这个问题有更好的标题,所以请提前阅读.想象一下,我们有一个封闭类型的族,它将每种类型映射到Maybe除了maybes之外的相应类型:

type family Family x where
  Family (Maybe x) = Maybe x
  Family x = Maybe x
Run Code Online (Sandbox Code Playgroud)

我们甚至可以使用该类型族声明一个函数:

doMagic :: a -> Family a
doMagic = undefined

exampleA = doMagic $ Just ()
exampleB = doMagic $ ()
Run Code Online (Sandbox Code Playgroud)

在GHCi中使用它表明可以评估此​​函数应用程序的类型:

*Strange> :t exampleA      
exampleA :: Maybe ()       
*Strange> :t exampleB      
exampleB :: Maybe ()       
Run Code Online (Sandbox Code Playgroud)

问题是,是否有可能提供该doMagic功能的任何实现除外undefined?举个例子说我想把每个值都包装成一个Just构造函数,除了Maybes应该保持原样,我怎么能这样做呢?我尝试使用类型类,但如果不使用封闭类型系列,则无法为doMagic函数编写可编译签名,有人可以帮助我吗?

Ed'*_*'ka 8

您可以使用另一种封闭式的家庭区分Maybe xx,然后你可以使用另一种类型类提供的不同实现doMagic了这两种情况.快速而肮脏的版本:

{-# 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 $ ()
Run Code Online (Sandbox Code Playgroud)