notes-computer-programming-haskell-haskellNotesMisc

notes for a future post


purpose

already a year out of date

difficult, two sources: different complex

language updates

memory strict

python examp

no typecasting boolean typecasting -> unreadable helpers

unreadable helpers

haskell collection are a mess

error messages

docs vs irc

homeoiconic, macros

static complexity

open data Open Data Types and Open Functions like 5 different frameworks to alleviate this no really generic (parsec needs to be rewritten to use ByteString??)

python/ruby compile to haskell

connection machines, non-composability of locks, next mainstream, functional is the right default


--- i think this is wrong : "execution ordering" annotation (do the parallel libraries already do this?). for example, say i have a very large file. i am parsing it line by line. each line generates two data objects, of types A and B. A objects and B objects are being fed into separate paths of data transformation (A -> A' -> A -> A, and B -> B' -> B -> B). The first two steps operate on individual X objects, but the final step in each path requires combining all of the X objects (that is to say, if you consider the list [A] of A objects, the first two steps are maps and the last one is a fold). After an A object has been turned into an A object, the A path has no more need of the original strings from the original input line. Similarly, after a B object has been turned into a B' object, the B path doesn't need the strings.

Now, my impression is that currently, Haskell is allowed to (and often will choose to) execute A -> A', and then A' -> A, and then A -> A. While it is doing this, however, it will read in the entire input file, and keep every line of it in memory because it knows that eventually it will have to compute the Bs, and the Bs depend on the lines.

What the programmer wants it to do is to process each line of input separately and then forget about it. But the programmer doesn't want to let this dirty, real-world concern affect the beauty of hir code; the programmer wants to keep the description of the a pipeline and the B pipeline totally separate, in separate functions, as much as possible.

So, what is needed is an way for the programmer to write these pipelines separately, and then only commingle them in a single place, by telling the compiler explicitly about the sad facts of life. The programmer should be able to annotate the string object created by reading in the line; the programmer wants to say, "once this thunk has been evaluated, you may execute neither the "A->A" function, nor the "B->B" function, until you have strictly executed both of "A'->A" and "B'->B". This can be effected by tricking the compiler into thinking that the following dependencies exist:

(note: you could do that by adding "seqs" to A->A and B->B, i guess..)


haskell overloading typeclass disallowed example

(also example of an error which is caught at compile time, but not until you try and use the ambiguous construct)

in file tst.hs:

data Dumbtype a b = Dumbtype a b

Nothin a b

instance Monad (Dumbtype a) where return r = Dumbtype undefined r Dumbtype a f >>= k = k f Nothin a f >>= k = k f

instance Monad (Dumbtype Char) where return r = Nothin 'a' r Dumbtype a f >>= k = k f Nothin a f >>= k = k f

:l tst

<interactive>:1:4: Overlapping instances for Monad (Dumbtype Char) arising from a use of `return' at <interactive>:1:4-13 Matching instances: instance Monad (Dumbtype a) -- Defined at tst.hs:(17,0)-(20,29) instance Monad (Dumbtype Char) -- Defined at tst.hs:(23,0)-(26,29) In the expression: return 'y' In the expression: do return 'y' :: Dumbtype Char Char In the definition of `it': it = do return 'y' :: Dumbtype Char Char


haskell typeclass debugging? example: I was looking at the expression "((*) >>= id) f", where f is of type String -> Int. Control.Arrow had been imported. I was wondering what kind of monad was being applied here, that is, which instance definition for typeclass Monad was defining ">>=" in my expression. The answer seems to be that Control.Arrow imports Control.Monad.Fix, which imports Control.Monad.Instances, which contains a Monad instance for functions.

Is there a way to ask GHCI to tell me the file in which it is finding the instance definition that it is using in a given expression? If not, then is there a way to ask GHCI to list all instance definitions currently accessible? Or, at least, a way to ask GHCI to list all files currently accessible (i.e. all modules loaded, as well as all modules imported by those modules, etc)? Thanks.

How do you do that? I'm hoping for something akin to :info, that will tell me, "in this expression, the >>= that is being used is found in file Control.Arrow".

Also, is there a way to get an evaluation

---

haskell notes:

(Num a, OnlyInts? a)

class OnlyInts? a where foo :: a -> a -> Bool

instance OnlyInts? Int where foo = (==)

bar :: (Num a, OnlyInts? a) => a -> Bool bar = foo 5

http://homepages.cwi.nl/~ralf/gpce06/ http://www.haskell.org/haskellwiki/Why_Haskell_matters http://www.haskell.org/haskellwiki/OOP_vs_type_classes http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html

http://www.haskell.org/tmrwiki/FpVsOo

let cross2 l1 l2 = do {x <- l1; y <- l2; if x < y then return (x,y) else fail ""} why doesn't this work: let cross2 l1 l2 = do {x <- l1; y <- l2; if x < y then return (x,y) else return ()} A: [()] != [] :t cross2

let cross3 l1 l2 = do {x <- l1; y <- l2; if x < y then return x*y else fail ""}

:t cross3

---

sparkie 1 day ago

link

I too dislike tutorials focused around the REPL, because it's rarely how you write code in practice. The REPL is more of a debugging tool for quickly testing and manipulating code you've already written.

I'd jump directly into creating code files/modules - begin by creating simple programs using `main` as you would in other languages. Create a file with ".hs" extension, (Haskell filenames start with capital letters by convention, since they share the name of the module)

    main :: IO ()
    main = putStrLn "Hello World!"

Make sure the GHC bianries are in your PATH, and use the program "runhaskell File.hs" to quickly compile and execute them. Also, from ghci you can use the command (:load File.hs), if you want to debug stuff.

The preferred tool for writing Haskell though is emacs. If you're not familiar with emacs, its also a great opportunity to learn. Grab emacs 24, and open the file ~/.emacs, paste in this snippet:

    (require 'package)
    (add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/"))
    (package-initialize)

Then hit M-x (M for Meta, which is typically Alt), and type eval-buffer into the minibuffer at the bottom. If no errors, hit M-x and type into the mini-buffer:

    package-install haskell-mode

You can add the following to the .emacs file and use `eval-buffer` again. Also save with C-x C-s.

    (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
    (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)

Next step is to just open an empty haskell file. Create a new directory for your project with `M-x make-directory`, and create a new haskell file using C-x C-f. Add some code, and hit C-c C-l (load in ghci), and emacs will pop open a new window, launch ghci and load your code into it.

You can switch over to the ghci window with C-x o (cycle windows), and type some code into it for testing. (Note it can be quite buggy if the cursor is not in the right place - there needs to be a space after the prompt > ¦). Useful keyboard shortcuts to remember here are M-p (previous) and M-n to cycle through previously used commands. (You can rebind any keys to how you wish.)

You can also add typicall IDE features like "run without debugging" and such with simple snippets of elisp. Say if we want to bind F6 to this command, we can add this hack to .emacs, save and eval the expression.

    (global-set-key [f6] 
        (lambda () 
            (interactive) 
            (async-shell-command (concat "runhaskell " buffer-file-name))))

Now with an active haskell file, F6 will launch like an application, bypassing GHCI - and emacs will typically open a new window (or replace an existing one) with the stdout/stderror for the application.

That'll get you started anyway. From there, using LYAH is a good beginner resource, although it won't get you much further than past the syntax and semantics of the core language. It doesn't cover the plethora of language extensions, building projects, using cabal, haddock, quickcheck and more. I'm not aware of a single resource which covers these though - I just learned what was needed as and when by searching - the best information typically comes from one-off blogs focused on a specific problem.


PieSquared? 1 day ago

link

You could try IHaskell[0] for playing around with Haskell. It is like GHCi, but provides a notebook interface where you can enter multiline expressions and do declarations, so it is a lot closer to real Haskell. (It can be a bit of a paint o install though.)

Disclaimer: IHaskell author here :)

[0] https://github.com/gibiansky/IHaskell

reply

TimFogarty? 1 day ago

link

It sounds like you're looking for Learn You A Haskell. Great book, free too read online, tells you how to start with Haskell step by step. http://learnyouahaskell.com/chapters

reply

berdario 1 day ago

link

I suggest you enable the `+m` flag for multiline input

This way, you don't have to use the weird curly braces trick (which I always forget), at the cost of having to type one more enter when entering a oneliner

FYI, this is my ghci.conf: https://github.com/berdario/dotfiles/blob/master/ghci.conf (I don't suggest a new user to use ClassyPrelude?)

That said, I'm not sure what learning material to suggest to you, but if google and stackoverflow.com fails you, try freenode#haskell

personally, I got a lot more interested in Haskell after starting with Clojure (it helped me to appreciate more things like immutable data structures)

reply

---

orbifold 1 day ago

link

This http://dev.stephendiehl.com/hask/ overview is a little bit more advanced. It gives a good overview over the tools, some of the ecosystem and important libraries.

reply

codygman 14 hours ago

link

A little more advanced, but this resource has been indispensable for me. Thanks Stephen!

reply

---

--

http://stefan.saasen.me/articles/git-clone-in-haskell-from-the-bottom-up/

---

http://dev.stephendiehl.com/hask/

--

---

a good writeup of the haskell record type problem, and pointers to various proposed solns:

the problem: http://nikita-volkov.github.io/record/

various proposed solns:

discussions:

https://news.ycombinator.com/item?id=8909126

---

Haskell module system proposal:

---

Haskell initial blog post on lenses:

---

http://code.haskell.org/~dons/talks/dons-google-2015-01-27.pdf

"

In - house Haskell compiler: `Mu’. One of Lennart’s many Haskell compilers. • Has a few language and runtime customizations:  Whole world optimizing compiler.  Largely strict( - ish ) evaluation strategy ( n.b . devs have very mixed view on this).  Compiles to portable bytecode – same blob runs on Linux or Windows.  Values, closures, functions can be serialized.  Primitive String type is a unicode text blob. No [Char].  `Any` type. For the dynamically typed boundary interfaces

...

Things we use – Haskell + Cortex • Usual things:  QuickCheck?  fclabels data structure lenses  Attoparsec ; blaze; bytestring ; cairo ; vector; HaXml? ; geniplate ; etc etc . • New things:  GUIs: Generate native Windows WPF GUI or JavaScript? app from single Haskell impl .  Data mining: In - language relational algebra data structures and API.  Memoization

In - language data flow graph library with memoization support.  Lens compiler. Derive data structure editor APIs for free.  Bindings: Tons of bindings to external services. Haskell as API glue.  Time and date: very good calendar; timezone ; datetime handling Common joke: “all bugs are calendar bugs”.

...

Useful things:  In - house haddock docs and type - based API search for corporate APIs  Ubiquitous lightweight, asynchronous logging.  Continuous, automated merge/test/integration/deploy infrastructure  Cross platform, distributed job scheduling. Like a dependency graph multi - host ` cron `. • Surprising things:  Heavy use of process isolation. Baby Erlang in Haskell . Assume the quant library; external service, whatever will fail. o Wrap it up in a process. o Monitor that process (pipes or zeromq ) o Log, restart, kill as necessary  Process for parallelism. (Data) parallelism via process `map`. o Same code scales from local threads to local processes, to remote, 1000+ node grid jobs o Parallel “strategies” and monadic workflows for parallelism.  Native relational algebra data type. o An awful lot of data mining and analysis is best done with relational algebra. o Not just in the database.

....

Not your usual type system: newtype Large systems are built from lots of smaller systems in conversation. How does the language help us specify valid communication channels? • Obvious first step: don’t use String and Double for all the things f :: Double - > Double - > String - > Double The type tells me basically nothing about what values are valid and what are illegal. “ Stringly - typed” programming. Erasure of information that would help the programmer. Do I pass percent values? Rates? Volatilities? Who knows? So name the things: f :: Rate Libor - > Spot SGD - > Date - > Rate SIBOR

Use ` newtype ` and `data` to distinguish unique entities in the system. Layer the semantics of the system over the underlying representation. Representation is only one thing we might say about a value’s meaning. newtype Tenor = Tenor String  Tenor “1M” newtype NonNegative? a = NonNegative? Double  3.14159 :: NonNegative? D5 newtype Spot newtype Forward newtype Bid newtype Ask newtype Today; newtype PrevDay? Make it impossible to mix up or combine values in nonsense ways.

Not your usual type system: phantom types Same concept (e.g. Rate, Spot, Forward, Bid, Ask) can appear in many circumstances. Need a generic way to tag values with type - level information: phantom types • Augments types with origin/security/other metadata. • Makes it possible to prove security properties, information flow properties • Very lightweight, but high power/expressiveness. • First steps down the road to GADTs and type level programs. Examples: data Ratio n = Ratio Double 1.234 :: Ratio D3 data Ask ccy

Ask Double

Ask 1.5123 :: Ask GBP Massively reduces the number of intended paths values may take in the system.

Not your usual type system: Boolean blindness As a dual to how String and Double types have too many valid values for most use cases, ` Bool ` often has too little information. This has been coined “Boolean blindness” by Harper. A Boolean value on its own tells me nothing about what it is that is true or false. What proposition was proved? Makes it too easy to dispatch in the wrong direction, or pass the truthiness of one proposition to some code that needed to know something else. Phantom types can help eliminate this. Compare: authenticate :: String - > String - > IO Bool With authenticate :: Priv p => User - > Passwd - > IO ( AuthUser? p) data Editor data Owner instance Priv Editor ; instance Priv Owner

Type tags to improve code A common technique when taking over someone’s code is to start introducing newtypes for each distinct value you come across. Name the concepts as you go.

"

---

i don't use Haskell myself because i consider it to be too hard to read, too verbose to write, and to be missing various useful conventions in core libraries. But then, i don't value typechecking as much as some. -- me


i wrote this:

One thing that Haskell does is put monads into the type signature. This allows you to typecheck impurity (side-effects and non-determinism), where by 'impurity' i mean a situation where a function either reads state other than through its input parameters (for example, reading a line of input from the user, or getting a random number from a random number generator, or using a global variable), or alters state other than through its return value (for example, printing out a line of output, writing to a logfile, getting a random number from a random number generator, or changing a global variable). In essence, you can look at impurity as out-of-band reading-from or writing-to global state. Haskell allows you to divide this 'global state' into named pieces, and then to characterize in the type signature exactly which pieces of state each function is allowed to access (and prohibiting any impurity which is not explicitly called out in the type signature). For example:

http://learnyouahaskell.com/for-a-few-monads-more#state

This is said to make programs less error-prone by making it absolutely clear to someone reading (or debugging) a piece of code all the ways in which one function could possibly affect the rest of the program.

---

Learn Physics by Programming in Haskell

http://arxiv.org/pdf/1412.4880v1.pdf https://news.ycombinator.com/item?id=9003898

---