2015-08-12 7 views
28

Ich bin kürzlich auf einen Bot auf Twitter namens EmojiHaskell gestoßen, der behauptet, "interpretierbaren Haskell-Code mit Emoji-Variablennamen" zu twittern. Ein besonderes Tweet erregte meine Aufmerksamkeit, da es für mich wie missgebildete Syntax aussah, also entschied ich mich, genauer hinzusehen. Bisher habe ich den folgenden Code produziert haben:Verwendung von Emoji in Haskell

module Main where 

:: [] -> Maybe 
[] = Nothing 
(:as) = Just 

main = print $ "♥" 

Da ich λ gelegentlich in meinem Haskell-Code verwendet haben, erwartete ich diesen Code zu arbeiten, aber es scheint, dass GHC nicht die Emoji mag überhaupt .

Mit $ runhaskell Main.hs ich:

Main.hs: 4: 1: Parsen Fehler bei der Eingabe ''

Ich habe bereits einen Blick auf die UnicodeSyntax Erweiterung hatte, und versuchte, um nur ein oder ein einzelnes Emoji anstelle von allen zu verwenden, um zu sehen, ob ein bestimmtes das Problem provoziert.

Jetzt ist meine Frage: Gibt es derzeit einen Haskell-Compiler, der den Code akzeptieren würde? Kann ich GHC irgendwie mit diesem Code arbeiten?

+1

Ich weiß nicht, ob Sie so viel Wert, aber Sie könnten einen Präprozessor machen. Afaik GHC hat eine Flagge, um einen benutzerdefinierten Präprozessor Ihrer Wahl auszuführen. – MasterMastic

+1

AFAIK, Unicode-Syntax ermöglicht es Ihnen, '->' mit '→' zu ersetzen, und so weiter. Es ist * nicht * erforderlich, nur Unicode-Zeichen in Ihrem Quellcode zu verwenden. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/syntax-extns.html#unicode-syntax – MathematicalOrchid

Antwort

35

Dieser Code ist ungültig haskell. Der Grund dafür ist, dass (wie wahrscheinlich alle Emojis) ist ein Symbolzeichen:

Prelude> import Data.Char 
Prelude Data.Char> generalCategory '' 
OtherSymbol 

Aber man kann sie immer noch wie jedes andere Symbol verwenden, nämlich als Betreiber:

Prelude Data.Char> let() = (+) 
Prelude Data.Char> 32 42 
74 

Weiterhin als user3237465 wies darauf hin, wenn Sie das Präfix Syntax für Operatoren, also setzen sie in Klammern, können Sie es sogar wie jedes andere Symbol verwenden:

() :: [a] -> Maybe a 
() [] = Nothing 
() (():as) = Just() 

main = print $() "♥" 

Dies ist fast das Beispiel in der ursprünglichen Nachricht. Leider funktioniert dieser Trick nicht für die Typvariable. Die the documentation ist ein bisschen leider formuliert, aber in fact Symbole sind nie Typ Variablen und immer Typ Konstruktoren

+1

Operatoren müssen nicht infix sein, das ist legal: '() [] = Nichts;() ((): as) = ​​Nur(); main = print $() "a" '. – user3237465

+0

Danke. Ich habe fälschlicherweise angenommen, dass '()' es zwingen würde, einen Funktionstyp zu haben, der zwei Argumente akzeptiert, aber das scheint nur für Operatorabschnitte der Fall zu sein. Bug [# 10772] (https://ghc.haskell.org/trac/ghc/ticket/10772) hat über das Problem geschrieben, dass es nicht auf der Typ-Ebene funktioniert. –

+0

Ah, sehr cool, das Update nach dem Hinweis von user3237465 zu sehen :) –