2015-02-26 18 views
7

"You Büyük İyi bir Haskell öğrenin!" Kendimi daha genel bir şekilde yeniden yazmak istedim.Bu durum ifadesi, görünüm kalıp sözdizimi ile nasıl yazılır? Ben bir <a href="http://learnyouahaskell.com/functionally-solving-problems#reverse-polish-notation-calculator">RPN calculator</a> örneğini okunduktan sonra

Mevcut işlevleri kolayca genişletmek için, bunlarısözdizimini kullanarak lookup işleviyle eşleşen ayrı listelere ve desenlere koydum. read ile giriş okumak için bu yazdı:

parse xs x = case readMaybe x of 
    Just x -> Right (x : xs) 
    Nothing -> Left "Syntax error 

ama yerine bir vaka ifadesini önlemek ve görünümü desen böyle tekrar kullanmak istiyorum: Ben alıyorum ikincisi ile Ancak

parse xs (readMaybe -> Just x) = Right (x : xs) 
parse xs (readMaybe -> Nothing) = Left "Syntax error" 

Bu hata: No instance for (Read a0) arising from a use of ‘readMaybe’

nedenini anlamıyorum. Onlar eşdeğer değil mi?

bütün kod here olduğunu.

cevap

11

Onlar eşdeğer değiller. case sürümünde bir readMaybe vardır, görünüm modelinin iki sürümü vardır. Her readMaybe için, derleyici, okuma girişiminin hedefi olan türden bir sonuç çıkarmalıdır. Kod

parse xs x = case readMaybe x of 
    Just x -> Right (x : xs) 
    Nothing -> Left "Syntax error 

dediğinde GHC dedektif sizin Just x durumunda, xxs için consed biter olduğunu fark eder ve böylece xs elemanları ne olursa olsun tipi almalıdır. Ve bu iyi bir iş. Eğer

parse xs (readMaybe -> Just x) = Right (x : xs) 
parse xs (readMaybe -> Nothing) = Left "Syntax error" 

yazarken

Ama iki ayrı buluntu-hedef-tipi sorunlarını, readMaybe her kullanım için bir tane oluşturun. Bunlardan ilki case durumunda olduğu gibi sadece aynı şekilde çözüldü, ama saniye, bu Okumak başarısız olduğunu ne sadece hayır ipucu yoktur

parse xs (readMaybe -> Nothing) = Left "Syntax error" 

, bireysel olarak okumak edilir ve Yukarıdaki satırdakiyle aynı şey olduğuna inanmak için hiçbir sebep yok.

Genel olarak, ilgilenilen tek sonucu olmadığı sürece görünüm kalıplarını kullanmak uygun değildir. Eğer kez bir ara hesaplama yapmak, ancak birden fazla durumda içine sonucunu analiz etmek istiyorsanız Yanlış sözdizimi vardır. Bu sebepten ötürü kendilerine bir yanlışlık olduğunu düşündüğüm kayıtlarda kalmaktan mutluluk duyuyorum.

+0

Tamam, teşekkürler. Davayı bende tutacağım. – Rnhmjoj

+0

Görünüm kalıpları, birçok durumda bir işlevinizle birlikte çok kullanışlıdır, ancak durumlar, bir Belki'i döndüren işlevler ile yapılır ve hiçbir zaman ara türdeki deseni eşleştirmezsiniz. Gibi şeyler f x | Sadece y <- g0 x = ...; Sadece y <- g1 x = ... 'f (g0 -> Sadece y); f (g0 -> Sadece y) '- ikincisi çok daha güzeldir çünkü işe yaramaz bir değişkeni (ilk durumda' x') bağlamaz. – user2407038

+1

Kesinlikle orta düzey hesaplamaları kullanan desen eşleştirmeyi desteklemeye değer. Sorun şu ki, görüş paternleri sadece bu Just-or-bust stiline iyi destek veriyor. Sol taraftan ayrılmak zorunda kalmadan bir ara hesaplamanın sonucu olarak birden fazla ısırığa sahip olmalıyız.Ancak, gereksiz ekstra isimlendirmenin can sıkıcı olduğu konusunda hemfikirim, bu yüzden biraz daha kompakt bir göstergeye sahip olmak yararlı olabilir (ara hesaplama sadece bir model değişkenine bağlı olduğunda ve bir kez eşleştirildiğinde) ve ayrıca fazladan bir isim yerine bir doğrusal olmayan kalıplar istiyorum. eşitlik muhafızı. – pigworker

İlgili konular