Вычислительные выражения для программиста на Haskell

Я хочу изучить F #, но одна вещь, которая меня смущает, - это синтаксис выражения вычисления (do-notation ??) и дешугаризация.

В haskell у вас есть очень простой класс типов Monad и правила для дешугаризации do-нотации в bind и return. В добавлении ключевых слов нет никакой магии; единственное, что должно совпадать, это типы.

В F# есть куча компоновщиков, ключевых слов и сложности.

Есть ли хорошее объяснение того, как сопоставить одно понятие с другим?

Я в основном хочу знать, как я сопоставляю

do
  x <- monadicComputation
  foo x
  someOtherMonadicComputation
  let y = somePureComputation x
  return $ bar y

to F#.

Единственными ключевыми словами в хаскеле являются do, (‹-) и let.


person nimish    schedule 25.10.2013    source источник


Ответы (3)


Вы не можете написать общий монадический код на F#, вместо этого вам нужно указать монаду, с которой вы работаете, назвав построитель, связанный с выражением. Ваш пример кода будет выглядеть так:

let example = async {
    let! a = someAsyncComputation
    foo a
    do! someOtherAsyncComputation
    let y = somePureComputation a
    return (bar y)
}

для типа выражения вычисления async. Шаблон «бах» (сделай!, позволь! и т. д.) используется при связывании монадических значений, в то время как обычные ключевые слова используются для немонадных значений.

let! соответствует привязке (>>=), а let соответствует let в нотации do. return соответствует return, а return! используется для получения существующего монадического значения. do! похож на (>>), который выполняет монадическое значение для своих эффектов, в то время как do предназначен для немонадных эффектов, не имеющих аналогов в Haskell.

person Lee    schedule 25.10.2013
comment
Я думаю, вы хотели сказать, что do! похож на (>>). - person MisterMetaphor; 25.10.2013
comment
Хотел бы я принять все эти ответы, но я возьму этот, так как кажется, что сообщество проголосовало за него больше всего. - person nimish; 28.10.2013

Если вы знакомы с Haskell, вам может быть интересна научная статья, которую я недавно написал о вычислительных выражениях F#.

Он связывает синтаксис выражения вычислений (который является достаточно гибким) со стандартными классами типов, которые используются в Haskell. Как уже упоминалось, F# не позволяет легко писать универсальный код поверх монады (это можно сделать, но это не идиоматично), но, с другой стороны, он позволяет выбрать наиболее подходящий синтаксис и может даже получить хороший синтаксис для MonadPlus или для преобразователей монад.

В дополнение к монаде async, упомянутой Ли, вот пример MonadPlus (используя выражение последовательности — монаду списка — в качестве примера):

let duplicate list = seq { 
  for n in list do 
    yield n 
    yield n ∗ 10 }

Или выражение вычисления для парсеров:

let rec zeroOrMore p = parse {
  return! oneOrMore p 
  return [] }
person Tomas Petricek    schedule 25.10.2013
comment
Я нашел этот ответ слишком поздно, и сейчас ссылка кажется неработающей. Не могли бы вы обновить свой ответ правильной ссылкой, пожалуйста? - person nicolocodev; 06.04.2016

Нотация haskell do имеет только один специальный синтаксис, т. е. <-, который сопоставляется с функцией bind, все остальное внутри do — это обычное приложение функции, для которого результатом является тип монады, например: return, putStr и т. д.

Точно так же в F # у вас есть let! для представления операции bind и синтаксического сахара ключевого слова return (не обычный вызов функции, как в haskell, но это ключевое слово сопоставляется с функцией Return, которую вы определяете). Теперь есть много других ключевых слов, которые могут поддерживать ваши вычислительные выражения (вы можете легко их опустить, если они не требуются). Все они задокументированы здесь. Эти дополнительные операции как бы дают вам синтаксический сахар для использования ключевых слов F# вместо обычных функций, возвращающих монадическое значение. Вы можете видеть, что все ключевые слова, которые вы можете перегрузить в вычислительных выражениях F#, имеют монадическое возвращаемое значение.

Таким образом, вам не нужно беспокоиться обо всех этих ключевых словах, просто думайте о них как о обычных функциях, возвращающих монады (с определенной сигнатурой типа, которую вы можете найти в документации), которые вы можете вызывать, используя ключевые слова F# внутри синтаксиса выражения вычисления. .

person Ankur    schedule 25.10.2013