2016-02-18 10 views
9

Strona Standard Haskell Classes mówi następujący temat reads :: (Read a) => String -> [(a,String)]:Kiedy może występować niejednoznaczny zapis z odczytami?

Normalnie, parser zwraca listę singleton, zawierające wartość typu A, który został odczytany z ciągu wejściowego oraz pozostały ciąg który następuje co analizowany . Jeśli jednak nie było możliwe przetwarzanie, wynikiem jest pusta lista, a jeśli istnieje więcej niż jedna możliwa analiza (niejednoznaczność), wynikowa lista zawiera więcej niż jedną parę.

W jakich sytuacjach lub przykładach ujawnia się ta niejednoznaczność?

+2

pomyśl o 'data Foo = F | Fo | Foo wyprowadza (Show, Read) 'i' czyta "FooBar" :: [(Foo, String)] ' – epsilonhalbe

+3

@epsilonhalbe ... niestety to nie zadziała w ten sposób (" czyta "FooBar" :: ... "będzie yield '[]') – Carsten

+1

Świetne pytanie! Domyślam się, że to się nigdy nie zdarza w standardowych typach bibliotek, ale 'reads' nadal odpowiada za możliwość, że użytkownik może chcieć zdefiniować reprezentację" kodu przedrostkowego "dla swoich własnych typów. (?) IMHO, uważam, że 'readMaybe' jest bardziej użyteczny w praktyce. – chi

Odpowiedz

2
import Text.Read 

data Foo = Bar Int | Baz Double deriving Show 

instance Read Foo where 
    readPrec = fmap Bar readPreC+++ fmap Baz readPrec 

W tym przykładzie, parser próbuje zanalizować Int i Double. Jeśli można go przeanalizować dla obu, analizator składni zwraca dwie wartości.

Wynikające w:

> read "4" :: Foo 
*** Exception: Prelude.read: ambiguous parse 

i

> reads "4" :: [(Foo,String)] 
[(Bar 4,""),(Baz 4.0,"")] 

Najprostszym sposobem tutaj, aby naprawić dwuznaczność jest, aby wybrać jedną parse zastępując choice operator +++ z selective choice <++.