如何在haskell中对两个参数进行模式匹配

Posted

技术标签:

【中文标题】如何在haskell中对两个参数进行模式匹配【英文标题】:How do I pattern match on two parameters in haskell 【发布时间】:2022-01-19 02:33:18 【问题描述】:

我对 Haskell 很陌生,如果有任何不正确或令人困惑的语法,我深表歉意。我已经大大简化了我正在尝试做的事情以使其更易于理解。

首先,我有两种用户定义的类型:

data Foo = A String | B Int | C

type Bar = (Int, String, [Int])

我正在尝试编写这样的函数:

myfunc :: Foo -> Bar -> Bar


--if Foo is A s,
--  increment intA
--  append s to stringA
--  return new Bar

myfunc (A s) intA stringA listA = (intA + 1) stringA++s listA 


--if Foo is B i, 
--  if listA[1]<listA[0]
--    increment intA by i
--    increment intA
--    return new Bar
--  else
--    increment intA
--    return new Bar

myfunc (B i) intA stringA (x:y:xs) = if y<x then ((intA+i)+1 stringA xs) else ((intA+1) stringA xs)



--if Foo is C,
--  increment intA
--  add listA[0], listA[1]
--  prepend to listA
--  return new Bar

myfunc (C) intA stringA (top:second:xs) = (intA + 1) stringA top+second:xs


因此,对于 Foo 的每个可能值,myfunc 都有不同的定义。

然后我想访问第二个参数 Bar 中的值,以返回一个“更新的”Bar,根据使用的 Foo 以不同的方式更新。

我目前在 myfunc (B i) 版本的 myfunc 上遇到错误:

Couldn't match type ‘(Int, String, [Int])’ with ‘[Bar]’
      Expected type: [Bar]
        Actual type: Bar

我将其解释为编译器期望Bar列表,我不明白。

【问题讨论】:

【参考方案1】:

Bar 值是单个元组,而不是 3 个单独的值。匹配现有值,并为返回创建一个新值,就像处理任何其他 3 元组一样。

myfunc (A s) (intA, stringA, listA) = ((intA + 1), stringA++s, listA)
-- etc

【讨论】:

感谢您的快速回复!抛出一个新错误:Couldn't match type ‘Int’ with ‘(Int, String, [Int])’ Expected type: Bar Actual type: Int - 这是在 myfunc 的相同(第二个)定义上,在将我 认为 适当的括号括起来之后:myfunc (B i) intA string (x:y:xs) = if y&lt;x then (intA+i+1, stringA, xs) else (intA+1, stringA, xs) - if 语句语法有什么问题? 同样的事情适用于其他情况:myFunc 总是接受 两个 参数;第二个是元组。三个单独的模式不匹配一个元组。

以上是关于如何在haskell中对两个参数进行模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

函数返回与函数参数中的 Haskell 模式匹配

如何在 Scala 中对对象进行模式匹配

Haskell 和 Erlang 中的模式匹配

Haskell:绑定模式匹配的地方

你如何在 Haskell 中使用模式匹配和元组列表?

Haskell:为什么++不允许模式匹配?