Using Emoji in Haskell - haskell

I've recently come across a bot on Twitter named EmojiHaskell, that claims to tweet 'interpretable Haskell code with emoji variable names'. A particular Tweet caught my attention, as it looked like malformed syntax to me, so I decided to take a closer look. So far I've produced the following code:
module Main where
🙏 :: [🍳] -> Maybe 🍳
🙏 [] = Nothing
🙏 (👽:as) = Just 👽
main = print $ 🙏 "♥"
Since I've used λ on occasion in my Haskell code, I expected this code to work, but it appears that GHC doesn't like the emoji at all.
With $ runhaskell Main.hs I get:
Main.hs:4:1: parse error on input ‘🙏’
I've already had a look at the UnicodeSyntax extension,
and tried to only use some or single emoji instead of all of them to see if a certain one provokes the problem.
Now my question is this:
Is there currently a Haskell compiler that would accept the code?
Can I get GHC to work with this code somehow?

That code is not valid haskell. The reason is that 🙏 (like, probably, all Emojis) is a symbol character:
Prelude> import Data.Char
Prelude Data.Char> generalCategory '🙏'
OtherSymbol
But you can still use them like any other symbol, namely as an operator:
Prelude Data.Char> let (🙏) = (+)
Prelude Data.Char> 32 🙏 42
74
Furthermore, as user3237465 pointed out, if you use the prefix syntax for operators, i.e. put it in parentheses, you can even use it like any other symbol:
(🙏) :: [a] -> Maybe a
(🙏) [] = Nothing
(🙏) ((👽):as) = Just (👽)
main = print $ (🙏) "♥"
This is almost the example in the original post. Unfortunately, this trick does not work for the type variable. The the documentation is worded a bit unfortunately, but in fact symbols are never type variables and always type constructors

Related

Can not use spltOn to split String on spaces

I have a string containing words separated by spaces. I would like to get the individual words.
I verified (in ghci) that the following solution works well:
import Data.String
list_of_words = words "a b c"
but I happened to stumble accross the splitOn function, and since I am still in the basement of Haskell programming, and a curious mind, I wondered whether I could also achieve my goal using this function. Hence I tried:
import Data.List
lw = Data.List.splitOn "a b c"
only to get the error message
Not in scope: ‘Data.List.splitOn’
No module named ‘Data.List’ is imported
I don't understand the first message, but the second one is ridiculous, since I imported the module, and the module name is shown in the ghci prompt. Then I realized that the website above referst to a module Data.List.Split, not Data.List. Hence I tried
import Data.List.Split
only to get the error messages
Could not find module ‘Data.List.Split’
Well, curiosity killed the cat. I should have stayed with my original words solution. But since I opened the box now, could some kind soul explain to me, why my attempts have failed, and how I could have it done correctly?
UPDATE Following the comments to my question, I tried
splitOn " " "a c d"
but this time get the error message
Variable not in scope: splitOn :: [Char] -> [Char] -> t
Perhaps you meant one of these:
‘Text.splitOn’ (imported from Data.Text),
‘splitAt’ (imported from Data.List),
‘Text.splitAt’ (imported from Data.Text)
It looks like Data.Text (which I happened to import too) also has a splitOn function with different signature. Hence, I started a fresh ghci without any imports, and just did a
import Data.List
splitOn " " "a b c"
This gave also the error message
Variable not in scope: splitOn :: [Char] -> [Char] -> t
Install the split library to be able to use it. Since you're a stack user here are the commands for that:
stack build split # install split (some people prefer "stack build" over "stack install", but the difference concerns only executables)
stack ghci # start ghci using the environment of packages installed by stack

Split a string by a chosen character in haskell

I'm trying to split a string every time there is a chosen character. So if I receive "1,2,3,4,5", and my chosen character is "," the result is a list such as ["1","2","3","4","5"].
I've been looking through the already answered questions in here and they point me to using splitOn. However, when i try to import Data.List.Split in order to use it, Haskell gives me the following error: Could not find module ‘Data.List.Split’ . When I tried to just use splitOnwithout importing the module, it showed me Variable not in scope: splitOn.
So my questions are,
Is it normal that i'm getting this error? Is splitOn a viable option or should I just try something else?
What other simple solutions are there?
I can just write something that will do this for me but I'm wondering why I'm not able to import Data.List.Split and if there are other simpler options out there that I'm not seeing. Thank you!
If you're using GHC it comes with the standard Prelude and the modules in the base package, and perhaps a few other packages.
Most packages, like the split package (which contains the Data.List.Split module), aren't part of GHC itself. You'll have to import them as an explicit compilation step. This is easiest done with a build tool. Most Haskellers use either Cabal or Stack.
With Stack, for example, you can add the split package to your package.yaml file:
dependencies:
- base >= 4.7 && < 5
- split
You can also load an extra package when you use Stack to start GHCi. This is useful for ad-hoc experiments.
‘Data.List.Split’ is not in prelude and needs to be installed as a dependency package.
Install command depends on environment you are using:
‘stack install split’ for stack
‘cabal install split’ for cabal
Basically this is a foldring job. So you may simply do like
λ> foldr (\c (s:ss) -> if c == ',' then "":s:ss else (c:s):ss) [""] "1,2,3,42,5"
["1","2","3","42","5"]
So;
splitOn x = foldr (\c (s:ss) -> if c == x then "":s:ss else (c:s):ss) [""]
However this will give us reasonable but perhaps not wanted results such as;
λ> splitOn ',' ",1,2,3,42,5,"
["","1","2","3","42","5",""]
In this particular case it might be nice to trim the unwanted characters off of the string in advance. In Haskell though, this functionality i guess conventionally gets the name
dropAround :: (Char -> Bool) -> String -> String
dropAround b = dropWhile b . dropWhileEnd b
λ> dropAround (==',') ",1,2,3,42,5,"
"1,2,3,42,5"
accordingly;
λ> splitOn (',') . dropAround (==',') $ ",1,2,3,42,5,"
["1","2","3","42","5"]

Haskell error - 'parse error on input `->'

I am trying to declare a function in Haskell GHCi as
fact :: Int -> Int
But I am getting this error - error: parse error on input `->'
I do not understand why this is happening. Can anyone please explain it to me? Thanks.
First off, it looks like you're using a pretty old version of GHC. In newer versions, the GHCi syntax has been relaxed a bit.
But still: what you type in GHCi does not have the same rules as what you write in a Haskell source file. Specifically, the GHCi prompt is essentially an IO monad chain evaluator, the reason being that you can write stuff like
Prelude> putStrLn "Hello"
Hello
or
Prelude> readFile "test.txt"
"fubar\nbaz"
and actually have it execute right there. By contrast, in a Haskell source file, you only declare bindings, and these can then be invoked in the main action or a GHCi session.
But in this case, you want to declare a binding within GHCi itself. You can do that too, but it's a bit awkward, basically you need to start with let and then squeeze everything in a single line:
Prelude> let fact :: Int -> Int; fact n = product [1..n]
Actually, newer GHCi version allow you to omit the let, and you can have multiple-line definitions by using a special bracket syntax:
Prelude> :{
Prelude| fact :: Int -> Int
Prelude| fact n = product [1..n]
Prelude| :}
but I would recommend against this. If you actually have some bigger definitions, better put them in a proper Haskell source and load that into GHCi.

Haskell: Parse error: module header, import declaration or top-level declaration expected

I am saving some commands in a Haskell script in a .hs file while working thru a Haskell textbook. Here's a small example.
fst (1,2)
snd (1,2)
When I run these commands from the prelude in GHCi, they work fine. When I try to compile the .hs file with these two lines, I get the following:
ch4_test.hs:2:1: error:
Parse error: module header, import declaration
or top-level declaration expected.
|
2 | fst (1,2)
| ^^^^^^^^^
Failed, no modules loaded.
I've googled this error and can't find any explanation what I'm doing wrong.
From a newbie to future newbies: The interactive environment ghci would lead you to believe that you can punch some expressions into an .hs file and run the thing (in a similar fashion to languages like swift and ruby). This is not the case.
Haskell needs an entrypoint called main. Quoting:
Here is a simple program to read and then print a character:
main :: IO ()
main = do c <- getChar
putChar c
The use of the name main is important: main is defined to be the entry point of a Haskell program (similar to the main function in C), and must have an IO type, usually IO ()
Source: https://www.haskell.org/tutorial/io.html
You can't just put any expression in a hs file.
As the error message says, you need a declaration here. For example:
main =
print (fst (1,2)) >>
print (snd (1,2))
I am getting this error but the cause appears to be completely different from anything posted here. And the error message is not at all helpful.
Using Cabal version 3.6.2.0 with GHCI 8.10.7 on MacOS High Sierra (10.13)
I'm working from this page: https://www.tutorialspoint.com/haskell/haskell_modules.htm
specifically the "custom modules" section. There you can see the code I copied and pasted.
Besides the tutorial not mentioning I needed to add "other-modules: Custom" to myfirstapp.cabal, and besides the fact that the sample Custom.hs file includes "if x 'rem' 2 == 0" rather than "if x rem 2 == 0", here is the problem:
Indentation matters!
This line (inside the quotes) does NOT work "if x rem 2 == 0".
This line DOES work " if x rem 2 == 0"!
Indenting by one space is the difference between success and failure.
I'm totally new to Haskell. I've programmed extensively in PHP, Javascript, and Applescript, and dabbled in a dozen others, and this is the first time I've seen white space matter. I assume this is commonly known amongst Haskell veterans, but it would certainly be nice if that was included prominently in the documentation.

Haskell: "Not in scope: '>>'" with no implicit prelude

Compiling the following Haskell program with GHC 6.12.1 yields an error:
{-# LANGUAGE NoImplicitPrelude #-}
module Example where
import Prelude(Integer, fromInteger, (==))
f :: Integer -> Integer
f n
| n == 0 = 0
Namely:
example.hs:9:6: Not in scope: `>>'
The error goes away when I change the import statement to:
import Prelude(Integer, fromInteger, (==), (>>))
This makes sense. What I don't understand, however, why there is an error in the first place. My program doesn't seem to make use of any Monad, while >> is one of the Monad operators.
I don't know the root cause of this problem, but if you compile your code with -ddump-rn-trace option on, you can see that the compiler for some reason puts (>>) into a list of definitions used, something like that:
finish Dus [(Nothing, [(314, Integer)]),
(Just [(rdd, f)], [(01D, >>), (01E, fromInteger), (01L, ==)]),
(Nothing, [])]
Most certainly it is a bug in GHC 6.12.1
This is a bug in ghc. You should report it.
I can imagine the compiler checks to see if >> is present (which it needs for compilation of do-blocks), no matter if do occurs in your code.
(But then, it should also complain about >>=)

Resources