gpt4 book ai didi

Haskell 模式匹配向量

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

我正在关注在线tutorial on Haskell 。我们定义一个函数来添加由数字元组对表示的二维向量。以下是显式类型声明,确保两个输入都是二维向量。

addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)

我理解为什么以下函数定义使用模式匹配:它描述了输入数据应符合的模式。

addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)  

为什么下面的替代函数定义不使用模式匹配? (fst) 和 (snd) 保证有效,因为输入被显式声明为长度为 2 的元组。

这两个函数定义有什么区别?

addVectors a b = (fst a + fst b, snd a + snd b)

最佳答案

它们的严格程度不同。假设我们重命名它们:

> let addVectorsStrict (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
> let addVectorsLazy a b = (fst a + fst b, snd a + snd b)

addVectorsStrict undefined undefinedundefined - 一旦需要结果的外部 (,) 构造函数,就会执行模式匹配:

> case addVectorsStrict (error "A") (error "B") of (_, _) -> ()
*** Exception: A

但是 addVectorsLazy undefined undefined(undefined, undefined) - 模式匹配被推迟,直到需要结果的一个元素 .

> case addVectorsLazy (error "A") (error "B") of (_, _) -> ()
()

基本上,addVectorsLazy 总是返回一个元组,其中的元素可能未被评估。 addVectorsStrict 可能不会返回。您还可以使用惰性模式匹配来获得 addVectorsLazy 的效果:

> let addVectorsAlsoLazy ~(x1, y1) ~(x2, y2) = (x1 + x2, y1 + y2)
> case addVectorsAlsoLazy (error "A") (error "B") of (_, _) -> ()
()

为了更好地理解计算顺序,您可以使用Debug.Trace.trace来观察它:

addVectors
(trace "first tuple evaluated"
(trace "x1 evaluated" 1, trace "y1 evaluated" 2))
(trace "second tuple evaluated"
(trace "x2 evaluated" 3, trace "y2 evaluated" 4))

关于 Haskell 中的求值,需要记住的基本一点是,它是由使用 case 和函数方程(脱糖到 case)的模式匹配驱动的。

在这种情况下,这并不重要,但是您可以惰性地编写函数,以避免在不需要其结果的情况下评估昂贵的计算,或者如果您知道某些结果总是会出现,则可以严格避免重击的开销 是需要的。

一般来说,最好使数据结构的字段严格,除非您需要它们变得惰性,并使您的函数变得惰性,除非您需要它们要严格。在这里,您可以创建一个严格的对类型来表示您的向量:

data Vector a = Vector !a !a

关于Haskell 模式匹配向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45624790/

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