Могут ли два или более уравнения, определяющих функцию в Haskell, использовать один и тот же блок where / let? - PullRequest
4 голосов
/ 06 мая 2009

Могут ли два или более уравнения, определяющих функцию в Haskell, использовать один и тот же блок where / let?

Позвольте мне представить надуманный пример для иллюстрации вопроса.

Сначала рассмотрим следующий код в качестве отправной точки:

someFunction v1 v2 v3 = difference ^ v3
   where
      difference = v1 - v2

Пока все хорошо. Но затем представьте, что мне нужно разобраться с «альтернативным случаем», где мне нужно вернуть ноль, если v3 == 99 и разница <4 (совершенно произвольно, но, скажем так, это мои требования). </p>

Моей первой мыслью было бы сделать это:

someFunction v1 v2 99 | difference < 4 = 0
someFunction v1 v2 v3 = difference ^ v3
   where
      difference = v1 - v2

Тем не менее, это не сработает, потому что первое уравнение для someFunction и второе уравнение для someFunction не совместно используют один и тот же блок where. В этом надуманном примере это не имеет большого значения, поскольку в блоке where есть только одна переменная («разность»). Но в реальной ситуации может быть большое количество переменных, и было бы недопустимо их повторять.

Я уже знаю, как решить эту проблему, используя охрану и имея только одно уравнение. Вопрос в том, существует ли способ для нескольких уравнений разделить одно и то же предложение where / let? Потому что кажется желательным иметь несколько уравнений с разными закономерностями, а не заставлять иметь только одно уравнение со многими охранниками.

Ответы [ 2 ]

12 голосов
/ 06 мая 2009

Один из вариантов - поднять функцию в сам блок where:

someFunction v1 v2 = f
    where
        f 99 | difference < 4 = 0
        f v3 = difference ^ v3
        difference = v1 - v2
0 голосов
/ 06 мая 2009

Я думаю, что вы не можете. Возможно, вашим лучшим решением будет что-то вроде:

someFunction v1 v2 v3 | v3==99 && difference<4 = 0
                      | otherwise = difference ^ v3
                      where difference = v1 - v2
...