gpt4 book ai didi

haskell - 如何在haskell中创建类的类型实例?

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

我是Haskell的新手。

我正在寻找是否有任何方法可以创建类类型的实例。

有没有办法让这段代码在不使用数据或新类型的情况下工作?

type N = ∀n. (n -> n) -> n -> n

instance Printable N where
print :: N -> IO ()
read :: String -> N

当我尝试在 GHCi 中加载模块时,它告诉我:
Illegal polymorphic or qualified type: N
In the instance declaration for ‘Printable N’

最佳答案

你在那里写的看起来很像一个类声明,而不是一个实例。也许你是这个意思?

class Printable n where
print :: n -> IO ()
read :: String -> n

请注意 n必须是小写的,因为这是你量化类的类型变量。如果你真的想定义一个实例,那么你,好吧,实例化 nN :
instance Printable N where
print n = ...
read str = ...

此时类型签名都是固定的(来自类定义),您需要编写的是这些函数的实际绑定(bind),因此它必须是 = ,而不是 :: .

问题是:为什么你仍然需要自己的类(class)?它只会导致与标准函数的名称冲突 printread这已经在前奏曲中。你实际上应该做的是用你的 N 实例化那些标准类。类型,即
instance Show N where
show n = ...
instance Read N where
readsPrec _ str = ...

也就是说,要回答您提出的实际问题:不,不可能为像 ∀ n . (n->n) -> n->n 这样的多态类型合理定义任何实例。 .编译器应该如何将其与更具体的类型(如 (Int->Int) -> Int->Int)区分开来,或更一般的,如 ∀ n m . (n->m) -> n->m ?这是相当绝望的。正确的做法是将它包装在一个新类型中;隐藏通用量化并允许编译器正确区分 N从其他类型。

或者,您可以只编写接受/产生 N 的单态函数直接地:
showChurch :: N -> String
showChurch n = ...
readsPrecChurch :: Int -> ReadS N
readsPrecChurch _ str = ...

实际上后一个对于类型系统来说已经太多了: ReadS N简称
readsPrecChurch :: Int -> String -> [(∀ n . (n->n) -> n->n, String)]

列表中的通用量化?哦哦。那是一种含蓄的类型。 GHC 确实有 -XImpredicativeTypes扩展,但它并没有真正起作用。

同样,通过不公开使用多态类型来避免这些问题。 Rank-N 类型(尤其是镜头)有一些很好的用途,但大多数时候它们完全是多余的和不必要的。肯定没有充分的理由实际使用这样的教堂数字。
newtype N = Church { getChurch :: ∀ n . (n->n) -> n->n }

将允许您毫无问题地定义任意实例或函数。而且,实际上,只是做
type N = Int

对于整数的所有标准实例当然也一样好......

关于haskell - 如何在haskell中创建类的类型实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38675945/

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