gpt4 book ai didi

haskell - 为什么 IsList 需要 toList?

转载 作者:行者123 更新时间:2023-12-03 16:18:14 24 4
gpt4 key购买 nike

使用 -XOverloadedStrings 时你可以实现IsString只需要一个函数fromString .
现在,如果您想使用字符串文字进行模式匹配,您还必须实现 Eq ,这是有道理的:

f :: MyString -> Bool
f "foo" = True
f _ = False

-- equivalent to
f x
| x == fromString "foo" = True
| otherwise = False
但是为什么 IsList-XOverloadedLists 一起使用的类型类要求您实现 toList ?
wiki唯一提到的 toList 的用例是模式匹配。
我明白了 Eq不足以进行列表模式匹配。
但是后来 toList应该在一个不同的类型类中,只有当你想使用列表模式匹配你的类型时才需要,就像 IsString不需要 Eq .
这对我来说令人讨厌的是条件 fromList . toList = id必须满足,但对于某些类型,例如,这根本无法保证。一个无序的集合,它不保证元素的顺序被保持。
这似乎非常不一致。

最佳答案

两个扩展中重载的只是一个符号。两种表示法的区别在于列表可以包含变量
( [x, y] ) 而字符串不能:Haskell 不会像 let x = "apple" in "I like {x} pie") 那样进行变量插值
当我在模式中使用任何一种表示法时,这种差异变得很重要:我希望能够在模式中绑定(bind)变量,例如

f :: MyList Int -> Bool
f [x, y] = x > y
...而,即使我可以使用字符串文字作为模式
 f :: MyString -> Bool
f "apple" = True
...那些永远不会绑定(bind)变量
要查看这带来的不同,假设 -XOverloadedLists将完全像 -XOverloadedStrings 那样翻译模式匹配.模式匹配
f [x,y] = x > y
将被翻译为
f z
| z == fromList [x, y] = x > y
但是 fromList [x, y]不是构造函数模式:对于给定的 z , x 可能有几个不同的值和 y这样 fromList [x, y] == z (在您的示例中,无序集合 {1, 2} 等于 fromList [1, 2] 但也等于 fromList [2, 1] - 那么 f {1, 2} 的结果应该是 True 还是 False
这表明要使模式匹配起作用, Mylist a需要与 [a] 同构,换句话说,一个 toList需要满足适当的法律。然后我们可以找到唯一的 x, y这样 z == fromList [x, y]通过申请 toListz ,所以翻译改为
f z
| toList z == [x, y] = x > y
或者,使用 view pattern (甚至不再需要 Eq 了):
f (toList -> [x,y]) = x > y
所以,最终,你的 IsList没有 toList 的类不允许重载列表模式,但仍然可以表示您的无序集合 {1, 2}使用列表符号 [1, 2] .但是我们会得到 -XOverloadedLists-XOverloadedListPatterns - 可能不值得麻烦。

关于haskell - 为什么 IsList 需要 toList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66804720/

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