Happy Haskell Programming
View the Project on GitHub kazu-yamamoto/hhp
Here is an example story not to type import Foo
when
you write a Haskell program.
Type the following signature.
Note that ByteString
can be completed with M-C-i
.
foo :: [ByteString] -> [ByteString] -> [ByteString]
C-xC-s
highlights the signature.
Typing M-t
on the line results in:
import Data.ByteString (ByteString)
foo :: [ByteString] -> [ByteString] -> [ByteString]
foo = undefined
Type M-C-m
to load symbols of Data.ByteString
.
Then edit the body of foo
.
Note that append
can be completed with M-C-i
.
import Data.ByteString (ByteString)
foo :: [ByteString] -> [ByteString] -> [ByteString]
foo bs1 bs2 = B.append <$> bs1 <*> bs2
C-xC-s
highlights the body.
Type M-t
to get:
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
foo :: [ByteString] -> [ByteString] -> [ByteString]
foo bs1 bs2 = B.append <$> bs1 <*> bs2
Consider the following broken example:
foo :: [a -> a] -> a -> a
foo xs = foldr bar id xs
where
bar = (:)
C-xC-s
highlights the 2nd line. M-?
displays the following:
Couldn't match type `[a -> a]' with `a -> a'
Expected type: (a -> a) -> (a -> a) -> a -> a
Actual type: (a -> a) -> [a -> a] -> [a -> a]
...
Even in this situation, C-cC-t
on id
displays a -> a
in the minibuffer. GHC’s -fdefer-type-errors
enables this magic.
Also, you can make use of GHC’s hole. Inserting _
before bar
and typing C-xC-s
results in highlighting the second line again:
foo :: [a -> a] -> a -> a
foo xs = foldr _bar id xs
where
bar = (:)
M-?
displays:
Found hole `_bar' with type: (a -> a) -> (a -> a) -> a -> a
Where: `a' is a rigid type variable bound by
the type signature for foo :: [a -> a] -> a -> a
at /Users/kazu/c.hs:3:8
Relevant bindings include
bar :: forall a. a -> [a] -> [a] (bound at /Users/kazu/c.hs:6:5)
xs :: [a -> a] (bound at /Users/kazu/c.hs:4:5)
foo :: [a -> a] -> a -> a (bound at /Users/kazu/c.hs:4:1)
...
Suppose you have:
filterNothing :: [Maybe a] -> [a]
Typing M-t
gets:
filterNothing :: [Maybe a] -> [a]
filterNothing = undefined
On the other hand, typing C-uM-t
gets:
filterNothing :: [Maybe a] -> [a]
filterNothing xs = _body