2015-08-12 22 views
28

Recentemente mi sono imbattuto in un bot su Twitter chiamato EmojiHaskell, che dichiara di twittare "codice Haskell interpretabile con nomi di variabili emoji". Un particolare Tweet ha attirato la mia attenzione, poiché mi sembrava una sintassi malformata, quindi ho deciso di dare un'occhiata più da vicino. Finora ho prodotto il seguente codice:Utilizzo di Emoji in Haskell

module Main where 

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

main = print $ "♥" 

Dal momento che ho usato λ a volte nel mio codice Haskell, mi aspettavo questo codice al lavoro, ma sembra che GHC non piace l'emoji a tutti .

Con $ runhaskell Main.hs ottengo:

Main.hs: 4: 1: Errore di analisi su input ''

Ho già dato un'occhiata al UnicodeSyntax estensione, e provato usare solo alcune o singole emoji anziché tutte per vedere se una certa causa provoca il problema.

Ora la mia domanda è questa: C'è attualmente un compilatore Haskell che accetterebbe il codice? Posso ottenere GHC per lavorare con questo codice in qualche modo?

+1

Non so se ti interessa molto ma potresti fare un preprocessore. Afaik GHC ha un flag per eseguire un preprocessore personalizzato di tua scelta. – MasterMastic

+1

AFAIK, Unicode Syntax consente di sostituire '->' con '→', e così via. Non * è * richiesto solo per usare caratteri Unicode nel codice sorgente. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/syntax-extns.html#unicode-syntax – MathematicalOrchid

risposta

35

Questo codice non è haskell valido. La ragione è che (come, probabilmente, tutti Emojis) è un personaggio simbolo:

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

ma è ancora possibile utilizzarli come qualsiasi altro simbolo, vale a dire come operatore:

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

Inoltre, come user3237465 sottolineato, se si utilizza la sintassi del prefisso per gli operatori, cioè messo tra parentesi, si può anche utilizzare come qualsiasi altro simbolo:

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

main = print $() "♥" 

questo è quasi l'esempio nel post originale. Sfortunatamente, questo trucco non funziona per la variabile type. Il the documentation è formulato un po 'sfortunatamente, ma i simboli in fact non sono mai di tipo variabili e scrivono sempre costruttori

+1

Gli operatori non devono essere infissi, quindi questo è legale: '() [] = Niente;() ((): as) = ​​Just(); main = print $() "a" '. – user3237465

+0

Grazie. Ho assunto erroneamente che '()' lo costringesse ad avere un tipo di funzione che accetta due argomenti, ma questo è solo il caso delle sezioni di operatore. Bug [# 10772] (https://ghc.haskell.org/trac/ghc/ticket/10772) archiviato per il fatto che non funzionava a livello di testo. –

+0

Ah, molto bello vedere l'aggiornamento dopo il suggerimento da parte dell'utente3237465 :) –