2013-02-01 13 views
5

Wiele funkcji w Haskell złożonych ze znaków specjalnych w Haskell to funkcje infix. Należą *, +, ==, / itp Aby uzyskać podpisy typu takich funkcji można umieścić funkcję w nawiasach i wykonać :t, tak:Jak uzyskać podpis typu funkcji zakresu w Haskell?

GHCi> :t (==) 
(==) :: Eq a => a -> a -> Bool 

chciałem spróbować i uzyskać podpis typu dla funkcja zakresu, [a..a], ale wygląda na to, że ta funkcja to infiks, ale może być używana tylko na liście []. Próbowałem wszystkich następujących, ale żaden nie działał:

GHCi> :t (..) 
<interactive>:1:2: parse error on input `..' 
GHCi> :t ([..]) 
<interactive>:1:3: parse error on input `..' 
GHCi> :t [..] 
<interactive>:1:2: parse error on input `..' 
GHCi> :t .. 
<interactive>:1:1: parse error on input `..' 

Czy ktoś wie, jak uzyskać podpis typu funkcji zakresu?

Odpowiedz

13

Funkcja .. nie jest funkcją, w rzeczywistości jest to cukier składniowy. Jest tłumaczony na jedną z kilku funkcji: enumFrom, enumFromThen, enumFromTo lub enumFromThenTo.

Nie może to być normalna funkcja, ponieważ ma cztery formularze, które działają na różne sposoby. Oznacza to, że wszystkie cztery z nich są ważne:

[1..]  -- enumFrom 1 
[1,2..] -- enumFromThen 1 2 
[1..10] -- enumFromTo 1 10 
[1,2..10] -- enumFromThenTo 1 2 10 

Te formularze wykorzystują cztery wymienione przeze mnie funkcje.

Jeśli był to zwykły operator, 1.. dałaby częściowo zastosowaną funkcję; zamiast tego tworzy listę. Co więcej, dla normalnej funkcji notacja będzie przetwarzana jako [1,(2..10)], gdzie w rzeczywistości wszystko zostanie przekształcone w pojedynczą funkcję, biorąc wszystkie trzy liczby jako argumenty.

Te funkcje są częścią klasy Enum, więc notacja .. działa dla dowolnego typu, który jest jej częścią. Na przykład możesz napisać [False ..] i uzyskać listę [False, True]. (Niestety, ze względu na obecne niejasności parsowania, nie można pisać [False..], ponieważ zakłada się, że False jest modułem.)

8

Spróbuj użyć lambda.

> :t \x y -> [x..y] 

notacja jest tylko cukier syntaktyczny dla enumFrom i enumFromTo więc tak naprawdę nie ma konwencjonalnego rodzaju.

Powiązane problemy