gpt4 book ai didi

haskell - 类型声明中的类型限制

转载 作者:行者123 更新时间:2023-12-02 10:01:33 25 4
gpt4 key购买 nike

有一个著名的类型级自然数示例:

data Zero
data Succ n

我对应用类型构造函数 Succ 时所需的限制有疑问。例如,如果我们想在函数定义中进行这样的限制,我们可以使用类和上下文,如以下代码所示:

class Nat n where
toInt :: n -> Int
instance Nat Zero where
toInt _ = 0
instance (Nat n) => Nat (Succ n) where
toInt _ = 1 + toInt (undefined :: n)

不可能用toInt(undefined::Succ Int),没关系。

但是如何在类型级别构造上实现类似的限制(也许使用一些高级类型扩展)?

例如,我想允许仅将类型构造函数 SuccZero 类型和某些内容一起使用,如下所示:Succ (Succ Zero) Succ(Succ(Succ Zero))等等。如何在编译时避免此类糟糕的示例:

type Test = Succ Int

(暂时没有编译错误)

P.S.:对我来说更有趣的是如何对最后一个示例的类型声明创建限制

最佳答案

现在,我们使用 DataKinds 扩展:

{-# LANGUAGE DataKinds, KindSignatures, ScopedTypeVariables #-}

-- N is a type, but is also a kind now
-- Zero, Succ Zero, ... are values, but are also type-level values of
-- kind N
data N = Zero | Succ N

-- (We could import Proxy the library, instead)
data Proxy (n :: N) = Proxy

-- Now n is restricted to kind N
class Nat (n :: N) where
toInt :: proxy n -> Int

instance Nat Zero where
toInt _ = 0
instance (Nat n) => Nat (Succ n) where
toInt _ = 1 + toInt (undefined :: Proxy n)

然后我们可以使用toInt (Proxy::Proxy (Succ Zero))。相反,toInt (Proxy::Proxy (Succ Int)) 会根据需要引发类型错误。

就我个人而言,我还会用更现代的东西替换代理,例如AllowAmbigouslyTypesTypeApplications,以便删除未使用的参数。

{-# LANGUAGE DataKinds, KindSignatures, ScopedTypeVariables,
AllowAmbiguousTypes, TypeApplications #-}

data N = Zero | Succ N

-- Now n is restricted to kind N
class Nat (n :: N) where
toInt :: Int

instance Nat Zero where
toInt = 0
instance (Nat n) => Nat (Succ n) where
toInt = 1 + toInt @n

将此用作toInt @(Succ Zero)toInt @n 语法选择类型类中的 n。它不对应于运行时交换的任何值,仅对应于编译时存在的类型级参数。

<小时/>

使用

type Foo = Succ Int

也会根据需要出错:

    • Expected kind ‘N’, but ‘Int’ has kind ‘*’
• In the first argument of ‘Succ’, namely ‘Int’
In the type ‘Succ Int’
In the type declaration for ‘Foo’

关于haskell - 类型声明中的类型限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56777941/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com