Могу ли я назвать сигнатуру функции?

Я передаю частично примененную функцию. Полная подпись:

import Data.Map as Map 
-- Update the correct bin of the histogram based on the min value, bin width,
-- the histogram stored as a map, and the actual value we are interested in.
updateHist :: Double -> Double -> Map.Map Bin Double -> Double -> 
              Map.Map Bin Double

Функция обновляет карту, в которой хранятся данные для гистограммы. Первые два параметра задают нижние границы интересующих нас данных, следующий — ширина ячейки для гистограммы. Я заполняю эти значения при запуске программы и передаю частично примененную функцию по всему модулю. Это означает, что у меня есть масса функций с такой подписью, как:

-- Extra the data out of the string and update the histogram (in the Map) with it.
doSomething :: String -> (Map.Map Bin Double -> Double -> Map.Map Bin Double) -> 
               Map.Map Bin Double

Это все прекрасно и модно, но писать "(Map.Map Bin Double -> Double -> Map.Map Bin Double)" довольно многословно. Я хотел бы заменить их все на «UpdateHistFunc» в качестве типа, но по какой-то причине у меня не получается.

Я старался:

newtype UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double

Это не удалось с ошибкой:

HistogramForColumn.hs:84:44: ошибка синтаксического анализа при вводе `->'

Что я делаю не так?


person Tim Perry    schedule 17.06.2011    source источник


Ответы (1)


Вы путаете type и newtype здесь?

Использование type определяет синоним типа, что вы, кажется, пытаетесь сделать, тогда как newtype создает новый тип, которому требуется имя конструктора, например, data.

Другими словами, вы, вероятно, хотите этого:

type UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double

... или, может быть, это:

newtype UpdateHistFunc = UpdateHistFunc (Map.Map Bin Double -> Double -> Map.Map Bin Double)

Последний, очевидно, необходимо «развернуть», чтобы применить функцию.


Для справки:

  • data определяет новый алгебраический тип данных, который может быть рекурсивным, иметь отдельные экземпляры классов типов, вводит дополнительный уровень возможной лени и все такое прочее.
  • newtype определяет тип данных с одним конструктором, принимающим один аргумент, который может быть рекурсивным и иметь отдельные экземпляры, но только для проверки типа; после компиляции он эквивалентен содержащемуся в нем типу.
  • type определяет синоним типа, который не может быть рекурсивным или иметь отдельные экземпляры, полностью расширяется при проверке типов и представляет собой не более чем макрос.

Если вас интересует семантическое различие между data и newtype в том, что касается «дополнительной лени», сравните эти два типа и возможные значения, которые они могут иметь:

data DType = DCon DType

newtype NType = NCon NType

Например, как вы думаете, что будут делать эти функции, если применить их к undefined по сравнению с DCon undefined и NCon undefined соответственно?

fd (DCon x) = x
fn (NCon x) = x
person C. A. McCann    schedule 17.06.2011
comment
@ Тим Перри: Это понятно. Значение newtype на удивление тонкое, и его легко перепутать с другими, особенно когда в большинстве объяснений подчеркиваются операционные характеристики (которые в основном подразумевают концептуальные различия, но это не сразу очевидно). - person C. A. McCann; 18.06.2011
comment
Как вы думаете, стоит ли оставить этот вопрос скрытым в StackOverflow? Ваше разъяснение данных, типа и нового типа было очень полезно для меня. В противном случае я бы проголосовал за удаление этого. Думаю, я не совсем понял, что для newtype нужен конструктор. Я был зациклен на том факте, что вещи, определенные с помощью newtype, были эквивалентны типу, который они содержат после компиляции. Я не понимал, что материал был новым типом данных и, следовательно, нуждался в конструкторе. Мне действительно нужен был синоним типа. Думаю, я уговорила себя оставить этот вопрос. Спасибо @camccann, как всегда, за подробный ответ. - person Tim Perry; 18.06.2011
comment
@Tim Perry: Почему любой вопрос остается без решения? В некотором смысле кажущиеся глупыми ошибки, сделанные людьми, которые не являются ни новичками, ни экспертами, имеют самые полезные ответы, потому что они указывают на концепции, в которых существующий материал может быть недостаточно ясным. Представьте, что кто-то совершает ту же ошибку, что и вы, и использует Google для поиска "parse error on input" newtype. Этот запрос уже выдает этот ответ в качестве второго результата! - person C. A. McCann; 18.06.2011
comment
Круто - мой вопрос почти известен! - person Tim Perry; 18.06.2011
comment
Интересно, почему Haskell вообще предоставляет ключевое слово newtype... Оно эквивалентно data с одним строгим полем, не так ли? - person Rotsor; 18.06.2011
comment
@Rotsor: У меня сложилось впечатление, что newtype когда-то был гораздо более отчетливым / другим, когда язык был впервые определен, и на самом деле это не то, что можно просто удалить. Но я довольно новичок в Haskell, условно говоря, поэтому вам лучше спросить кого-то, кто работает более пары лет. - person C. A. McCann; 19.06.2011