gpt4 book ai didi

haskell - 您可以在类型类约束参数上对构造函数进行模式匹配吗?

转载 作者:行者123 更新时间:2023-12-03 22:00:15 25 4
gpt4 key购买 nike

请参阅下面的代码示例。它不会编译。我曾认为这可能是因为它必须为测试函数中的第一个参数提供单一类型。但这没有意义,因为如果我不对其进行模式匹配以便编译,我可以同时调用它 MyObj11 5MyObj21 5这是两种不同的类型。

那么是什么限制了您不能对具有类型类约束参数的构造函数进行模式匹配?或者有什么机制可以帮助你?

class SomeClass a where toString :: a -> String

instance SomeClass MyType1 where toString v = "MyType1"
instance SomeClass MyType2 where toString v = "MyType2"

data MyType1 = MyObj11 Int | MyObj12 Int Int
data MyType2 = MyObj21 Int | MyObj22 Int Int

test :: SomeClass a => a -> String
test (MyObj11 x) = "11"
test (MyObj12 x y) = "12" -- Error here if remove 3rd line: rigid type bound error
test (MyObj22 x y) = "22" -- Error here about not match MyType1.

最佳答案

what is it that restricts so you can't pattern match on constructors with a type class constrained parameter?



当您在显式构造函数上进行模式匹配时,您将提交特定的数据类型表示。这种数据类型并非在类的所有实例之间共享,因此根本不可能以这种方式编写适用于所有实例的函数。

相反,您需要将所需的不同行为与每个实例相关联,如下所示:
class C a where 
toString :: a -> String
draw :: a -> String

instance C MyType1 where
toString v = "MyType1"

draw (MyObj11 x) = "11"
draw (MyObj12 x y) = "12"

instance C MyType2 where
toString v = "MyType2"

draw (MyObj22 x y) = "22"

data MyType1 = MyObj11 Int | MyObj12 Int Int
data MyType2 = MyObj21 Int | MyObj22 Int Int

test :: C a => a -> String
test x = draw x

你原来的分支 test功能现在分布在实例之间。

一些替代技巧涉及使用 class-associated data types (您向编译器证明数据类型在所有实例之间共享),或 view patterns (它可以让你概括模式匹配)。

查看模式

我们可以使用 View 模式来清理模式匹配和类型类实例之间的连接,让我们通过共享类型上的模式匹配来近似跨实例的模式匹配。

这是一个例子,我们编写了一个函数,有两种情况,它可以让我们对类中的任何内容进行模式匹配。
{-# LANGUAGE ViewPatterns #-}

class C a where
view :: a -> View

data View = One Int
| Two Int Int

data MyType1 = MyObj11 Int | MyObj12 Int Int

instance C MyType1 where
view (MyObj11 n) = One n
view (MyObj12 n m) = Two n m

data MyType2 = MyObj21 Int | MyObj22 Int Int

instance C MyType2 where
view (MyObj21 n) = One n
view (MyObj22 n m) = Two n m

test :: C a => a -> String
test (view -> One n) = "One " ++ show n
test (view -> Two n m) = "Two " ++ show n ++ show m

注意 ->语法让我们回调到右边 view每个实例中的函数,查找每个类型的自定义数据类型编码,以便对其进行模式匹配。

设计挑战是想出一个 View 类型来捕获您感兴趣的所有行为变体。

在您最初的问题中,您希望每个构造函数都具有不同的行为,因此实际上没有理由使用 View 类型(在每个实例中直接调度该行为已经足够好)。

关于haskell - 您可以在类型类约束参数上对构造函数进行模式匹配吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5758343/

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