我正在尝试编写一个Data.Typeable.gcast适用于 kind 类型系列的变体* -> *。我正在寻找的是:
{-# LANGUAGE TypeFamilies #-}
import Data.Typeable
type family T
gcastT :: (Typeable a,Typeable b) => T a -> Maybe (T b)
gcastT = undefined -- but that's not working too well!
以此类推gcast :: (Typeable a,Typeable b) => f a -> Maybe (f b)。
这可能吗?
我可以将上下文更改为,(Typeable (T a),Typeable (T b)) =>但出于美学原因,我更喜欢这个签名:毕竟gcast不需要。Typeable1 f
一些背景,以防我解决了我真正想要实现的错误问题:我的目标是编写一个函数matchAndExtract:
matchAndExtract :: (Eq a, Typeable a, Eq b, Typeable b) => a -> b -> T b -> Maybe (T a)
matchAndExtract x k v = if (cast x == Just k) then gcastT v else Nothing
它检查xandk是否属于同一类型并且相等,然后返回提供的T b(我们那时知道它与T a- T 可能不是单射的,但它是一个函数!)或Nothing,否则。
我有一个解决方法,将违规内容包装T a在 a newtype、 using 中gcast,然后再次展开:
matchAndExtractF :: (Eq a, Typeable a, Eq b, Typeable b) => a -> b -> f b -> Maybe (f a)
matchAndExtractF x k v = if (cast x == Just k) then gcast v else Nothing
newtype WrapT a = WrapT { unWrapT :: T a }
matchAndExtractViaWrap :: (Eq a, Typeable a, Eq b, Typeable b) => a -> b -> T b -> Maybe (T a)
matchAndExtractViaWrap x k v = fmap unWrapT $ matchAndExtractF a k (WrapT v)
但这只是让我误会了!这也适用于T a不是 ; 的实例的实例Typeable。在我看来,这再次表明Typeable (T a)不需要上下文。
解决方法是完全可以接受的,但我想摆脱虚假WrapT类型。