Haskell模式匹配向量
我正在关注一个在线
tutorial on Haskell.我们定义了一个函数来添加二维向量,由元组对数字表示.以下是显式类型声明,它确保两个输入都是二维向量.
addVectors :: (Num 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 + y2) > let addVectorsLazy a b = (fst a + fst b,snd a + snd b) addVectorsStrict undefined undefined未定义 – 只要求结果的外(,)构造函数,就会执行模式匹配: > 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,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中评估的基本要点是,它是由使用大小写和函数方程的模式匹配驱动的(这与desugar到case). 在这种情况下并不重要,但是如果你的结果永远不需要,你可以懒散地编写你的函数以避免评估昂贵的计算,或者如果你知道总是需要一些结果,那么严格来避免thunk的开销. 一般来说,最好使数据结构的字段严格,除非你需要它们是懒惰的,并且除非你需要它们是严格的,否则你的函数会变得懒惰.在这里你可以制作一个严格的对类型来表示你的向量: data Vector a = Vector !a !a (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |