Как предоставить явное объявление типа для функций при использовании GHCi?

82

Как определить эквивалент этой функции (взятый из Learnyouahaskell ) внутри GHCi?

import Data.List  

numUniques :: (Eq a) => [a] -> Int  
numUniques = length . nub  

Без объявления типа GHCi принимает определение функции, но в конечном итоге получает бесполезный тип:

Prelude Data.List> import Data.List 
Prelude Data.List> let numUniques' = length . nub
Prelude Data.List> :t numUniques'
numUniques' :: [()] -> Int

Результирующая функция принимает в качестве параметра только список единиц.

Есть ли способ предоставить объявления типов в GHCi? Или есть другой способ определения таких функций, который не требует объявления типов?

Я не увидел очевидных подсказок в руководстве GHCi и поэкспериментировал с такими выражениями (безрезультатно):

> let numUniques' = ((length . nub) :: (Eq a) => [a] -> Int)
> :t numUniques'
numUniques' :: [()] -> Int
Mattbh
источник

Ответы:

101

Есть ли способ предоставить объявления типов в GHCi?

let numUniques' :: (Eq a) => [a] -> Int; numUniques' = length . nub

Или есть другой способ определения таких функций, который не требует объявления типов?

Если вы отключите ограничение мономорфизма с -XNoMonomorphismRestriction, будет выведен правильный тип.

sepp2k
источник
3
Я еще не знаком с мономорфизмом, но в целом этот ответ указал мне на использование точек с запятой для группировки определений в GHCi - учебные пособия написаны как в файле .hs, что дает много разных проблем при попытке в GHCi (функции не имеют привязки и т. Д. .).
Томаш Гандор
Стоит отметить, что -XNoMonomorphismRestrictionGHCi включен по умолчанию, начиная с 7.8.1: downloads.haskell.org/~ghc/latest/docs/html/users_guide/…
N. Shead
13

Обратите внимание, что вы также можете избежать ограничения мономорфизма, просто добавив «точки» (т.е. явные переменные) обратно в ваше выражение. Таким образом, это также дает правильный тип:

пусть numUniques x = длина. кусок $ x

sclv
источник
1
Спасибо - это здорово знать.
mattbh
Это известно как эта-расширение
Bladt
3

В Руководстве пользователя GHC показаны два дополнительных способа достижения этого. В этом подразделе представлена конструкция :{... :}, которую можно использовать следующим образом:

> :{
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| :}

Как вариант, вы можете включить многострочный режим :

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 
Рейнир Торенбек
источник