2013-04-18 4 views
9

Я изучаю Haskell с тех пор, так что я новичок.Haskell полиморфные вызовы без знания полного типа

Следующий код очень легко и понятно:

purStrLn $ show [1] 

Здесь мы можем вывести все типы (по умолчанию с), и все работает хорошо. Но следующий код работает, тоже:

putStrLn $ show [] 

даже если мы не можем определить тип списка.

Если я выполнить код с GHCI я получаю следующее:

Prelude> [] 
[] 
Prelude> :t it 
it :: [a] 
Prelude> 

поэтому тип, кажется, полиморфный. Но в этом случае шоу будет вызываться с частично применяемым типом.

Такое же поведение характерно для других типов, например Data.Map.empty, поэтому оно не является функцией списка (или, по крайней мере, кажется).

Почему и как это работает?

+0

'purStrLn $ показать [1]' по-прежнему имеет значение по умолчанию для типа, а '[1] :: (Num n) => [n]' – amindfv

+0

Это правда, но в таких случаях есть значения по умолчанию. – Totoro

+2

Обратите внимание, что что-то еще происходит, когда переменная типа не ограничена, например, например. 'length []', см .: http://stackoverflow.com/q/7076517. – hammar

ответ

16

Прежде всего, это работает только в ghci. Если вы пытаетесь скомпилировать эту программу с ghc вы получите ошибку типа:

Test.hs:3:19: 
    Ambiguous type variable `a0' in the constraint: 
     (Show a0) arising from a use of `show' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the second argument of `($)', namely `show []' 
    In the expression: putStrLn $ show [] 
    In an equation for `main': main = putStrLn $ show [] 

Добавление сигнатуры делают ошибки уходят:

module Main where 

main = putStrLn $ show ([]::[Int]) 

Но почему она работает в ghci? Ответ extended type defaulting в ghci: тип a по умолчанию - () (тип единицы измерения).

Мотивация такого поведения заключается в том, что пользователю очень сложно указывать типы при работе в интерпретаторе. Как Витус отмечает в комментариях, работает ghci с -Wall (или добавлением :set -Wall к вашим ~/.ghci) делает его легче обнаружить Нарушивший:

<interactive>:2:12: 
    Warning: Defaulting the following constraint(s) to type `()' 
       (Show a0) arising from a use of `show' 
    In the second argument of `($)', namely `show []' 
    In a stmt of an interactive GHCi command: it <- putStrLn $ show [] 
+3

Кроме того, набрав ': set -Wall' в GHCi, вы можете определить это значение по умолчанию. – Vitus

+0

Отлично, это очень пояснительный ответ :) – Totoro

Смежные вопросы