2017-02-11 15 views
0

Может кто-то пожалуйста, объясните, почему это компилируетсятипа Установка дробных к Мнимая

Prelude> 1 :: Num a => a 

и это не

Prelude> 1.0 :: Num a => a 

Второй пример будет работать с Fractional, но Num является суперкласс Fractional. Так же, как суперкласс Integral.

ответ

4

Если мы имеем

x :: Num a => a 

пользователь может выбрать xa, как хотел. Например.

x :: Int 

Что бы это оценили, если x = 1.5?

По этой причине литерал с плавающей запятой не может быть присвоен полититу Num a => a, так как его значение не будет (в общем) соответствовать всем Num eric типам.

Интегральные литералы вместо этого подходят для каждого числового типа, поэтому они допускаются.

+0

спасибо @chi. имеет смысл, когда вы так выразились :) поэтому '1 :: Num a => a' имеет значение true для любого' a', который является экземпляром 'Num', а' 1.0' - нет. – rodic

+1

@rodic Да. Теоретически разработчики Haskell могли бы утверждать, что '1.0' обрабатывается так, как если бы это было' 1', но на практике было бы ужасно запутанно обнаруживать, что в данном контексте тип '1.0' проверяет, но' 1.5' делает не. Таким образом, '1.0' разрешалось только представлять значения типов в классе« Fractional ». – chi

+0

Да, у меня было какое-то поплавок, когда я писал 1.0. но теперь я понимаю, что мой первоначальный вопрос можно переписать так: почему '1 :: a' не компилируется. Большое спасибо за помощь. – rodic

3

Отношение суперкласса между классами классов не установить отношения между типами. Это говорит нам о том, что только если тип т является членом класса типа C и B супер класс C, то т будет также членом В.

Это не сказать, что каждое значение v :: гр может быть использован при любом типе, который также является членом B. Но это то, что вы заявляете с:

3.14159 :: Num a => a 
3

Это важно различать полиморфизм объектно-ориентированные языки и полиморфизм в Haskell. OO polymorphism is covariant, while Haskell's parametric polymorphism is contravariant.

Что это означает: в ОО-языке, если у вас есть

class A {...} 
class B: A {...} 

т.е. A является суперкласс B, то любое значение типа B также значение типа A. (Обратите внимание, что любой конкретный значение на самом деле не полиморфный, но имеет конкретный тип!) Таким образом, если у вас

class Num {...} 
class Fractional: Num {...} 

то значение Fractional действительно может быть использовано в качестве значения Num. Это примерно то, что означает ковариант: любое значение подкласса is also a superclass value; иерархия значений идет в том же направлении, что и иерархия типов.

В Haskell, class es разные.Нет такой вещи, как «значение типа Num», только значения конкретных типов a. То, что типа может быть в классе Num.

В отличии от ОО-языков, значение как 1 :: Num a => aявляется полиморфными: он может взять на себя весь тип требований охраны окружающей среды, при условии, что тип в Num классе. (На самом деле этот синтаксис только обсчитывать для 1 :: ∀ a . Num a => a, следует читать как «для всех типов a, вы можете иметь значение 1 типа a). Например,

Prelude> let x = 1 :: Num a => a 
Prelude> x :: Int 
1 
Prelude> x :: Double 
1.0 

Вы также можете дать x более конкретное ограничение Fractional, так как это подкласс Num. Это просто ограничивает какой тип полиморфного значение может быть реализовано на:

Prelude> let x = 1 :: Fractional a => a 
Prelude> x :: Int 

<interactive>:6:1: 
    No instance for (Fractional Int) arising from a use of ‘x’ 
    ... 
Prelude> x :: Double 
1.0 

потому Int не дробный типа.

Таким образом, полиморфизм Haskell является контравариантным: полиморфные значения, ограниченные суперклассом, также могут быть ограничены подклассом, но не наоборот. В частности, вы можете, очевидно,

Prelude> let y = 1.0 :: Fractional a => a 

(y таким же, как x'), но вы не можете обобщить это y' = 1.0 :: Num a => a. Что хорошо, как заметил Инго, поскольку в противном случае можно было бы сделать

Prelude> 3.14159 :: Int 
    ???? 
+0

получил. num - это не такой тип, как в оо, а набор типов и для того, чтобы val был полиморфным, он должен быть способен создавать экземпляр любого типа num, любое другое правило приведет к абсурдным ситуациям, как вы, ребята, показали. – rodic