2015-01-25 3 views
5

Просто начав работу в Haskell, и я пытаюсь найти лучший способ назначить несколько переменных на основе одного условия. До сих пор я только что упаковывал и распаковывал кортежи. Есть ли лучший/более идиоматический способ?Назначение нескольких переменных в Haskell

(var1, var2, var3) = 
    if foo > 0 
     then ("Foo", "Bar", 3) 
     else ("Bar", "Baz", 1) 

Также интересуется стоимостью упаковки и распаковкой кортежей. Если я правильно читаю this, похоже, что это оптимизируется в функциях, но не уверен, что так происходит с назначением.

+1

Вы также можете использовать списки, просто чтобы вы знали. Вы даже можете сопоставить его в больших кусках, используя '(a: b: c: rest) = [1,2,3,4,5,6]' где 'a = 1',' b = 2', 'c = 3' и 'rest = [4,5,6]'. Кроме того, это необходимо только в операциях 'let' и' where', а не в уровне базового выражения. – AJFarmar

+9

Поскольку у нас нет переменных _mutable_ в Haskell, мы называем эти «привязки» или «определения», а не «присваивания». Ваш код выглядит хорошо, и я не буду беспокоиться о стоимости, если на него не будут указаны профилирующие очки. Кроме того, если вы беспокоитесь об этом кортеже, вы не хотите знать, как '' Bar "' фактически отображается во время выполнения ... ;-) – chi

ответ

6

Да, это прекрасно. Если вы скомпилируете с включенными оптимизациями, кортежи действительно будут «распакованными», поэтому они не будут иметь дополнительных затрат. Код будет преобразован в чем-то отдаленно, как это:

(# var1, var2, var3 #) = 
    case foo > 0 of 
     False -> (# "Bar", "Baz", 1 #) 
     True -> (# "Foo", "Bar", 3 #) 

распакованный 3-кортеж на самом деле только три значения, он не имеет какой-либо дополнительной структуры. В результате он не может быть сохранен в структуре данных, но это нормально. Конечно, если во время компиляции известно foo, то также будет оптимизировано case, и вы получите только три определения.

Смежные вопросы