SML преобразования в Haskell - PullRequest
       18

SML преобразования в Haskell

3 голосов
/ 09 апреля 2011

Несколько основных вопросов по конвертации кода SML в Haskell.
1) Я привык иметь локальные встроенные выражения в коде SML, например, тестовые выражения, распечатки и т. Д., Которые выполняют локальные тесты и выводят, когда код загружается (оценивается). В Haskell кажется, что единственный способ получить результаты (оценку) - это добавить код в модуль, а затем перейти к main в другом модуле и добавить что-нибудь для вызова и печати результатов.

Это правильно? в GHCi я могу набирать выражения и видеть результаты, но можно ли это автоматизировать? Мне неудобно переходить на главный уровень для каждой оценки теста - может быть, просто нужно сменить мою парадигму на лень.

2) в SML я могу выполнить сопоставление с образцом и унификацию возвращаемого результата, например,

val myTag(x) = somefunct(a,b,c);

и получите значение x после совпадения.

Можно ли сделать что-то подобное в Haskell легко, без написания отдельных функций извлечения?

3) Как создать конструктор с аргументом кортежа, т. Е. Безуспешно.
в SML:

Тип данных Thing = Информация о Int * Int;

но в Хаскеле я пытался;

Data Thing = Info (Int Int)

, что не получается. («Int применяется к слишком многим аргументам в типе: несколько Int») Карри версия отлично работает,

data Thing = Info Int Int

но я хотел без карри.

Спасибо.

Ответы [ 4 ]

5 голосов
/ 09 апреля 2011
  • Этот вопрос немного неясен - вы спрашиваете, как оценивать функции в Haskell?

Если речь идет о вставке отладки и трассировки в чистый код, это обычно требуется только для отладки.Чтобы сделать это в Haskell, вы можете использовать Debug.Trace.trace, в базовом пакете .

Если вас беспокоит вызов функций, программы на Haskell оцениваются от main и ниже, в зависимостипорядок.Однако в GHCi вы можете импортировать модули и вызывать любую функцию верхнего уровня, какую пожелаете.

  • Вы можете вернуть исходный аргумент функции, если хотите, сделав его частью результата функции, например, с помощью кортежа:

    f x = (x, y) where y = g a b c

Или вы хотите вернуть то или иное значение?Затем с помощью тегового объединения (типа суммы), такого как Either:

f x = if x > 0 then Left x
                else Right (g a b c)
  • Как мне сделать конструктор с аргументом кортежа, то есть неиспользованным в SML

Использование конструктора (,).Например,

 data T = T (Int, Int)

, хотя более Haskell-подобный будет:

 data T = T Int Bool

, и на практике это должны быть строгие поля:

 data T = T !Int !Bool
4 голосов
/ 09 апреля 2011
  1. Debug.Trace позволяет печатать сообщения отладки в режиме реального времени. Однако, поскольку эти функции используют unsafePerformIO, они могут вести себя неожиданным образом по сравнению с языком вызова по значению, таким как SML.

  2. Я думаю, что синтаксис @ - это то, что вы ищете здесь:

    data MyTag = MyTag Int Bool String
    
    someFunct :: MyTag -> (MyTag, Int, Bool, String)
    someFunct x@(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
    
  3. В Haskell типы кортежей разделяются запятыми, например, (t1, t2), поэтому вам нужно:

    data Thing = Info (Int, Int)
    
1 голос
/ 09 апреля 2011

Читая другие ответы, я думаю, что могу привести еще несколько примеров и одну рекомендацию.

data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]

someFunct :: Char -> Char -> Char -> ThreeConstructors

MyTag x = someFunct 'a' 'b' 'c'

Это похоже на примеры "let MyTag x = someFunct abc", но это топуровень модуля.

Как вы заметили, верхний уровень Haskell может определять команды, но нет никакого способа автоматически запускать какой-либо код только потому, что ваш модуль был импортирован другим модулем.Это полностью отличается от Схемы или SML.В Схеме файл интерпретируется как выполняемый по форме, но верхний уровень Haskell - это только объявления.Таким образом, библиотеки не могут делать нормальные вещи, такие как запуск кода инициализации при загрузке, они должны предоставлять команду «pleaseRunMe :: IO ()» для выполнения любой инициализации.требует некоторого стандартного кода, чтобы перечислить их все.Вы можете обратиться к группе Testing от hackage за полезными библиотеками, такими как test-framework-th .

1 голос
/ 09 апреля 2011

Для # 2, да, сопоставление с образцом Хаскелла делает то же самое.И let, и where выполняют сопоставление с образцом.Вы можете сделать

let MyTag x = someFunct a b c
in ...

или

...
where MyTag x = someFunct a b c
...