Возвращать определенный тип внутри Haskell

У меня довольно общий вопрос о системе типов Haskell. Я пытаюсь ознакомиться с ним, и у меня есть следующая функция:

getN :: Num a => a getN = 5.0 :: Double 

Когда я пытаюсь скомпилировать это, я получаю следующую ошибку:

 Couldn't match expected type `a' against inferred type `Double' `a' is a rigid type variable bound by the type signature for `getN' at Perlin.hs:15:12 In the expression: 5.0 :: Double In the definition of `getN': getN = 5.0 :: Double 

Как я понимаю, функция настроена так, чтобы «возвращать» тип в classе Num. Двойной находится в этом classе ( http://www.zvon.org/other/haskell/Outputprelude/Num_c.html ), поэтому я ожидал, что в этом случае было бы «возвратить» Двойное.

Может кто-нибудь объяснить это, пожалуйста?

Ожидается, что функция с сигнатурой Num a => a будет работать для любого типа в classе Num . Реализация 5.0 :: Double работает только для одного типа, а не для всех типов classа, поэтому компилятор жалуется.

Примером общей функции может быть:

 square :: (Num a) => a -> a square x = x * x 

Это работает для любого типа, который является Num . Он работает для удвоений, целых чисел и любых других чисел, которые вы хотите использовать. Из-за этого он может иметь общую подпись типа, которая просто требует, чтобы параметр находился в classе Num . (Тип classа Num необходим, потому что функция использует умножение с * , которое определено там)

Чтобы добавить к ответу sth: Haskell не является объектно-ориентированным. Неверно, что Double является подclassом Num , поэтому вы не можете вернуть Double если вы обещаете вернуть полиморфное значение Num , как вы можете, например, в Java.

Когда вы пишете getN :: Num a => a вы обещаете вернуть значение, полностью полиморфное в пределах ограничения Num . Эффективно это означает, что вы можете использовать только функции classа Num типа, такие как + , * , - и fromInteger .

Проверьте экзистенциально количественные типы .

Один из способов его решения – определить новый тип данных

 data NumBox = forall n. Num n => NumBox n 

Для этого вам понадобится -XExistentialQuantification .

Теперь вы можете написать что-то вроде

 getN :: NumBox getN = NumBox (5.0 :: Double) 

Вы также можете определить список NumBox как

 let n3 = [NumBox (4.0 :: Double), NumBox (1 :: Integer), NumBox (1 :: Int) ] 
  • Почему / когда использовать `intptr_t` для литья типов в C?
  • Когда использовать значения без знака над подписанными?
  • Вычисление переменной с использованием переменной типа
  • Использование `inline` в F #
  • Как проверить соответствие типа переменной Тип, хранящийся в переменной
  • .NET. Определите тип этого «classа» в статическом методе
  • Как напечатать тип или class переменной в Swift?
  • JAXB: Как изменить имена classов, сгенерированных XJC, когда тип attr указан в XSD?
  • Что такое тип данных uintptr_t
  • unsigned short в java
  • Что такое декларации и деклараторы и как их типы интерпретируются стандартом?
  • Давайте будем гением компьютера.