我正在阅读24 天 GHC 扩展的 Rank-N-Types 部分,并遇到了以下 GADT:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
import Data.Char
data Some :: * -> * where
SomeInt :: Int -> Some Int
SomeChar :: Char -> Some Char
Anything :: a -> Some a
unSome :: Some a -> a
unSome (SomeInt x) = x + 3
unSome (SomeChar c) = toLower c
unSome (Anything x) = x
unSome (someInt 2) -- 5
尽管unSome
它的类型变量是多态的,但可以向编译器证明,在这种SomeInt
情况下,给给定值加三是安全的。作者将这种类型称为细化。
现在我很好奇我是否可以对 Scrott 编码类型做同样的事情。幸运的是,有一个这样的编码示例。我们只需要打开 Rank-N-Types 和 Type-Families 扩展:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
newtype SomeC a =
SomeC {
runSomeC ::
forall r.
((a ~ Int) => Int -> r) ->
((a ~ Char) => Char -> r) ->
(a -> r) ->
r
}
但是,unSome
文章中没有提供。我不精通 Haskell,也不知道如何使用 Scott 编码来实现这个功能。尤其是类型等式约束(例如(a ~ Int) =>
)让我感到困惑。
感谢您提供有关其他在线资源的任何帮助或信息。