Як надати явні оголошення типу для функцій при використанні 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

Відповіді:


101

Чи є спосіб подати декларації типу в GHCi?

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

Або існує інший спосіб визначити такі функції, які не вимагають оголошень типів?

Якщо вимкнути обмеження мономорфізму за допомогою -XNoMonomorphismRestriction, воно виведе правильний тип.


3
Я ще не з мономорфізмом, але загалом ця відповідь вказала мені на використання крапок з комою для згрупування визначень у GHCi - підручники написані як у файлі .hs, що створює безліч різних проблем при спробі в GHCi (функції не мають прив'язки тощо .).
Томаш Гандор,

Варто зазначити, що -XNoMonomorphismRestrictionза замовчуванням для GHCi увімкнено з 7.8.1: downloads.haskell.org/~ghc/latest/docs/html/users_guide/…
N. Shead,

13

Зверніть увагу, що ви також можете уникнути обмеження мономорфізму, просто додавши "точки" (тобто явні змінні) до свого виразу. Отже, це також дає правильний тип:

нехай numUniques x = довжина. nub $ x


1
Дякую - це чудово знати.
mattbh

Це відоме як ета-розширення
Бладт

3

Посібник користувача GHC показує два додаткові способи досягнення цього. Цей підрозділ вводить конструкцію :{... :}, яку можна використовувати наступним чином:

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

Крім того, ви можете ввімкнути багаторядковий режим :

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.