Haskell是否允许let表达多个模式匹配?

teh*_*atz 7 haskell functional-programming pattern-matching let

假设我有一个函数可以进行一些计算,有几种模式; 以模式匹配的形式实现.

大多数这些模式(以及其他不同的东西)对参数进行处理,我在let表达式中使用中间变量.但我发现let在许多模式上使用相同的方法确实是多余的,我想知道是否有一种方法可以let为多种模式定义?

这是我复制的一个例子let:

data MyType a = Something a | Another Int [a]

myFunc (Something x) = -- return something, this isn't the point here
myFunc (Another 0 xs) =
    let intermediary = some $ treatment xs
    in doSthg intermediary 1 
myFunc (Another 1 (x:xs)) =
    let intermediary = some $ treatment xs
    in doSthg1 intermediary 1 x
myFunc (Another 2 (x:x':xs)) =
    let intermediary = some $ treatment xs
    in doSthg2 intermediary 2 x x'
Run Code Online (Sandbox Code Playgroud)

你可以看到,xs当我使用它时,参数总是存在intermediary,这可能是因素分解.它可以很容易地通过使用辅助函数来实现,但我想知道如果没有一个我的问题是否可行.请尽量让初学者保持简单,我希望我的例子足够清楚.

yat*_*975 7

这个特殊问题可以解决如下:

myFunc2 (Something x) = returnSomething x
myFunc2 (Another n ys) = 
    let xs = drop n ys
        x = head ys 
        x' = head (tail ys)
        intermediate = some $ treatment xs 
    in case n of
        0 -> doSomething intermediate n
        1 -> doSomething1 intermediate n x
        2 -> doSomething2 intermediate n x x'
Run Code Online (Sandbox Code Playgroud)

感谢懒惰的评估x,x'只有在需要它们的价值时才会进行评估.

但是 - 这是一个很大的问题!- 当你尝试调用时myFunc2 (Another 2 [])(和doSomething2实际使用的x!)你的代码会给出一个运行时错误,因为要找出x我们需要评估的是什么,head ys并且那个空列表会崩溃.您作为示例提供的代码也不起作用(另一个运行时错误),Another 2 []因为没有匹配的模式,但是更容易提供后备情况.

如果你控制输入并且总是确保列表Another足够长,这可能不是问题,但重要的是要注意这个问题!