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

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

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: ошибка синтаксического анализа на входе `- > '

Что я делаю неправильно?

Ответ 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 vs. DCon undefined и NCon undefined, соответственно?

fd (DCon x) = x
fn (NCon x) = x