[ cyb / tech / λ / layer ] [ zzz / drg / lit / diy / art ] [ w / rpg / r ] [ q ] [ / ] [ popular / ???? / rules / radio / $$ / news ] [ volafile / uboa / sushi / LainTV / lewd ]

λ - programming

/lam/bda /lam/bda duck
Name
Email
Subject
Comment
File
Password (For file deletion.)

BUY LAINCHAN STICKERS HERE

STREAM » LainTV « STREAM

[Return][Go to bottom]

File: 1431301001154.png (49.19 KB, 1000x716, url.png) ImgOps iqdb

 No.5965[View All]

Let's have a proper Haskell thread!
Post learning resources (beginner & advanced), neat tricks, stuff you wish you'd have known about sooner or simply talk about Haskell projects you are working on.

Currently reading the Haskell WikiBook at http://en.wikibooks.org/wiki/Haskell
I personally prefer it over lyah since lyah lacks exercises (I still skim through it since it is fun to read).
I also plan to work through "Thinking Functionally with Haskell" by Richard Bird, are there any opinions on this?
127 posts and 17 image replies omitted. Click reply to view.
>>

 No.11537

>>11504
Writing code doesn't imply understanding.

>>

 No.11618

Can someone educate me on what the best practice for the folder structure of a small Haskell project is?

Still a bit confused on this.

>>

 No.11621

>>11618
Copy the `stack init` structure and stuff should be ok.

>>

 No.11628

Come, write Haskell

https://coderpad.io/2Z9D94AE

>>

 No.11648

Can you guys recommend me some advanced haskell resources?
I'm currently at the level of understanding monad transformers (having read Real World Haskell).
What's the best way to go from here on out?

>>

 No.11656

>>11648
Have you checked out Functional Pearls?
As for advanced books, I can only recall two from the top of my head:
- Okasaki: Purely Functional Data Structures
- Bird: Pearls of Functional Algorithm Design

Hope it helps. Let me know if you need some more pointers or are looking to expand in a specific direction.

>>

 No.11670

>>11656
Thanks for the reccomendations.
I have no specific direction right now.
I know that there are a few more concepts, like comonads and arrows I have to learn about.
I also believe there's quite a few neat things the type system can offer if you enable some GHC extensions, which I don't know much about either.

>>

 No.11699

File: 1446978199091.jpg (127.34 KB, 1200x1850, awodey.jpg) ImgOps Exif iqdb

>>11670
I don't think there are any books specifically aimed on the more advanced Haskell-category-theoretical concepts like comonads, but there are some blogs that you might want to check out. Three I can think of right now:
> Dan Piponi's 'A Neighborhood of Infinity'
http://blog.sigfpe.com/
> Bartosz Milewski's Programming Cafe http://bartoszmilewski.com/
> The Comonad Reader
http://comonad.com/reader/

If you like Functional Pearls, you might also like the Monad Reader: https://themonadreader.wordpress.com/

If you're feeling _really_ adventurous, you might just as well jump straight into the rabbit hole, and peruse something like Awodey's 'Category Theory'. Alternatively or in parallel, check out the videos and lecture notes from the Oregon Programming Languages Summer School: https://www.cs.uoregon.edu/research/summerschool/summer12/curriculum.html
It's been going for eleven years now (2005–2015), adjust the URL as needed for more sweetnes.

>>

 No.11700

>>11656
Is there a full version of Purely Functional Data Structures, or is the thesis the final version?

>>

 No.11702

File: 1446981237204.djvu (3.47 MB, Purely-Functional-Data-St….djvu)


>>

 No.11704

>>11670
There's also the Typeclassopedia: https://wiki.haskell.org/Typeclassopedia

>>

 No.11721

>>11670
>>11704
This, it's the easiest introduction to all these classes.

I studied category theory before knowing Haskell exists, and the feeling is not exactly the same. While I think CT is amazing and pure love, don't start reading mathematics books, it will not help you very much with Haskell.

>>

 No.11724

File: 1447029754831.jpg (52.06 KB, 1024x1024, :^).jpg) ImgOps Exif iqdb


>>

 No.11764

>>11648
I just found this guide:
https://github.com/bitemyapp/learnhaskell/blob/master/specific_topics.md
It seems to cover a lot of the advanced topics, maybe it can be of use to someone else as well.

>>

 No.11851

Can someone help me setup my basic, global stack config?
I read
https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md

It says to put


templates:
params:
author-name: Your Name
author-email: youremail@example.com
category: Your Projects Category
copyright: Copyright: (c) 2015 Your Name
github-username: yourusername


into the config.yaml. But when I put it in there like this, I get an InvalidYaml error. I can't find a proper config.yaml example.

>>

 No.11852

>>11851
>Copyright:
the problem. enclose in quotes if you need that.

>>

 No.11853

>>11852
thank you very much! that did the trick

>>

 No.11985

How do people keep up with the Haskell world?

I've been working in Haskell semi-regularly since ~2008, and have been pretty comfortable with the language's developments and felt that I've been at least somewhat in the loop. Though suddenly, it looks like there have been lots of changes that I only now hear of.

For example, I seem to have completely missed the Foldable-Traversable-Proposal and Monads finally becoming a superclass of Applicative and Functor. And when did people move to stack? I'm still not entirely sure what problem it solves (it's not cabal hell, from what I've gathered).

Have I been living under a rock without realizing it?

>>

 No.11988

>>11985
You've just been free from side effects this whole time.

>>

 No.11989

>>11985
There are only two resources that I peruse that keep me up to date: the haskell-cafe mailing list, and /r/haskell.

The former I read weekly only to catch up on some interesting discussions, should they take place, but they're usually reposted on Reddit anyway.

The latter, I visit twice a day to twice a week. There is usually at least one interesting thread on the front page, and I can easily catch up with the breaking news by looking at the top topics in the last week or so.

>>

 No.12028

File: 1447651915832.jpg (42.41 KB, 669x746, 1435194745803.jpg) ImgOps Exif iqdb


>>

 No.12068

File: 1447776309345.jpg (36.63 KB, 960x639, comfy_by_marustagram-d81jp….jpg) ImgOps Exif iqdb

>>11988
mfw no side effects

>>11985
I'd also recommend the mailing list as well as /r/haskell, also follow some of the popular "haskell guys" on twitter
#haskell IRC also often has interesting discussions on current topics

>>

 No.12135

trying to get my first tiny haskell program running, i read and write something from one file to another, it works fine if I use readfile on "file.txt", but how do I access a file if it is not in the same folder as the source file itself? "../folder/file.txt" does not work

>>

 No.12144

>>12135
Yes it does. Are you sure you got the path right?

$ mkdir a b
$ echo "hello" >> a/foo
$ cd b
$ ghci
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> readFile "../a/foo"
"hello\n"

>>

 No.12151

>>12135
Absolute paths work too.

>>

 No.12156

Just found these slides about type classes.
Especially the second part about instance resolution could also be of interest to advanced haskellers.
http://people.cs.kuleuven.be/~tom.schrijvers/Research/talks/lhug_s02e01.pdf

>>

 No.12158

>>12135
If you want to find the path of a data file to be included with your project, cabal auto-generates a module called
Paths_yourproject
that defines the install directories. Any data files (declared with
data-files
in your .cabal) would then end up in the data directory.

Example of the generated module:

$ cat dist/build/autogen/Paths_balls.hs
module Paths_balls (
version,
getBinDir, getLibDir, getDataDir, getLibexecDir,
getDataFileName, getSysconfDir
) where

import qualified Control.Exception as Exception
import Data.Version (Version(..))
import System.Environment (getEnv)
import Prelude

catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
catchIO = Exception.catch

version :: Version
version = Version [0,1,0,0] []
bindir, libdir, datadir, libexecdir, sysconfdir :: FilePath

bindir = "/home/me/src/balls/.cabal-sandbox/bin"
libdir = "/home/me/src/balls/.cabal-sandbox/lib/x86_64-linux-ghc-7.10.2/balls-0.1.0.0-GyafO7tudcU0z1rnW9wBU3"
datadir = "/home/me/src/balls/.cabal-sandbox/share/x86_64-linux-ghc-7.10.2/balls-0.1.0.0"
libexecdir = "/home/me/src/balls/.cabal-sandbox/libexec"
sysconfdir = "/home/me/src/balls/.cabal-sandbox/etc"

getBinDir, getLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
getBinDir = catchIO (getEnv "balls_bindir") (\_ -> return bindir)
getLibDir = catchIO (getEnv "balls_libdir") (\_ -> return libdir)
getDataDir = catchIO (getEnv "balls_datadir") (\_ -> return datadir)
getLibexecDir = catchIO (getEnv "balls_libexecdir") (\_ -> return libexecdir)
getSysconfDir = catchIO (getEnv "balls_sysconfdir") (\_ -> return sysconfdir)

getDataFileName :: FilePath -> IO FilePath
getDataFileName name = do
dir <- getDataDir
return (dir ++ "/" ++ name)


So, you could run getDataDir or getDataFileName to find your file. To override the default paths, you could use the
--prefix
flag for
cabal configure
before building the project or set the
yourproject_datadir
environment variable when calling the program. Not sure how to use the former option with stack, though, if you're using that.

>>

 No.12337

>>12158
This is a nice thing to know, thank you lainon.

>>

 No.12346

Hi fellow haskellers, I come to you with a question as well: How do I pass functions of an imported module?

Let's say I got Module A which imports a library, and a Main.hs which imports Module A, how do I use specific functions from the library in my Main.hs?

I know I could import the library in my Main.hs as well, but this seems redundant to me.

>>

 No.12347

GHC replacement without FTP when?

>>

 No.12348

>>12347
Use Hugs or GHC 7.8. But why the hell would you want it? You just lose power.

AMP is less clear for me, as I'm not 100% sure that the monad you find useful in your code is always derived from the applicative you find useful. But still, it is nice.

>>

 No.12349

>>12346
You have to import them explicitely. Or if you want to use few things, use:

import Data.List (sort)

and say exactly what you are using in your code.

If that bothers you fundamentally, maybe you could modularize better your code.

>>

 No.12350

Why do Haskellites exaggerate the complexity of monads?

>>

 No.12351

>>12350
Once you understand what monads are, and why they exist, you lose the ability to explain it to anybody. – Douglas Crockford

>>

 No.12352

>>12350
To feel superior to others.

>>

 No.12353

>>12349
>maybe you could modularize better your code

guess you are then, thank you though

>>

 No.12354

>>12353
*right

>>

 No.12355

>>12350
They do not exaggerate, it is just vocabulary-heavy and you get used to it. And this is the kind of stuff that is very easily and clearly expressed with the right vocabulary, and just vague when you use non-technical words.

>>

 No.12356

>>12355
I like the saying "Enlightenment is being able to explain to the ignorant."

In other words, if you can't explain the concept in plain english to someone, you probably don't actually know what you're talking about.

In the case of monads, they seem to be the usual mental masturbation, so it's only exacerbated.

>>

 No.12357

>>12356
You can make methaphors and make the person feel she understood, but in most cases you just really learn by doing.

There are two cases where you want to explain things to laymen. One is when they are learning it so they can use it. In this case, they have to get a hold in it and really understand. The second case is when you are justifying your work, trying to make people interested, etc... In this case you just want to make people feel they understood the basic, but in most cases it's just a temporary sensation.

I don't really believe that you teach people, they learn with what you say. There are better or worse ways, but neither is done without work.

And monads in Haskell are very far from being mental masturbation. It is an abstraction, but one that allows you to do a really large quantity of stuff elegantly and efficiently.

People are just afraid of new words.

>>

 No.12359

>>12350
Where did you gain that impression? Literally every tutorial and attempt at explaining monads I've read starts with or contains something like "monads are really simple".

>>12356
It doesn't make sense to explain it in "plain English". Sure, you can use analogies and metaphors (burritos, kek), but the explanation will only be limited to a narrow abstraction of a particular instance of the concept. The "problem" with monads is that they're very abstract, and natural languages like English are not fit for this level of abstraction.

>>

 No.12360

>>12357
>>12359
This all reminds me of a different conversation I was having with a Haskell programmer.

I had grown unfamiliar with the term function composition. Of course I knew what it was, since I use it so often, but the Haskell programmer acted like he was superior because he remembered the term.

Since this is a Haskell thread, how about you two just try to explain monads? Anything abstract can be boiled down slowly to less abstract concepts.

>>

 No.12361

>>12360
>Since this is a Haskell thread, how about you two just try to explain monads? Anything abstract can be boiled down slowly to less abstract concepts.

A monad is a parameterised type along with definitions of fmap, pure, (<*>), and (>>=) satisfying the functor, applicative, and monad laws. That's it.

>>

 No.12362

>>12361
That's a good start.
Now define the following:
parameterised type
definitions
fmap
pure
(<*>)
(>>=)
satisfying
functor, applicative, and monad laws

>>

 No.12363

>>12360
>the Haskell programmer acted like he was superior because he remembered the term.
He was probably just a pretentious cunt.

>how about you two just try to explain monads?

Just look at one one of the myriad tutorials that have been written over the years: https://wiki.haskell.org/Monad_tutorials_timeline
There's no point in repeating the same points and making the same mistakes that lead to confusion along the way. If you have any specific points you want to discuss, bring them up.

>>

 No.12385

>>12363
>If you have any specific points you want to discuss, bring them up.
I wanted to read the first tutorial from the 90s, but it wasn't available.

My understanding is now that monads support returning values and also feeding them into other computations with >>=.
I've read that you can add on to this, although not shown how you can, to get state, IO, and exceptions.
From this, I've been told that monads let you create an environment that only has what you need.

That sounds interesting and reminds me of the package system in Common Lisp. I can avoid including whatever features I want in a package. I can also modify the read table global variable to disable access to features. It would be possible to replace Common Lisp's exception system with my own by aggressively creating such a package and access to certain datatypes can be restricted easily by simply disallowing use of functions and reader macros that create them.

>>

 No.12386

>>12385
>I wanted to read the first tutorial from the 90s, but it wasn't available.
Weird. I seem to have had it in cache, but after flushing, the server doesn't respond. It's in the Archive anyway: https://web.archive.org/web/20150423203821/http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf

>>

 No.12390

>>12385

Here's how you (could) define a state monad:

newtype State s a = State { runState :: s -> (a, s) }


"State s a" is a box containing a function of type "s -> (a, s)", which can be extracted with "runState". So here, the "state" is a represented as a single value: you supply an initial state, and you get back a result and a final state.

instance Functor (State s) where
fmap :: (a -> b) -> State s a -> State s b
fmap f sa = State $ \st -> let (a, st') = runState sa st in (f a, st')


The Functor instance lets you apply a function to the result value, possibly changing its type. It doesn't let you do anything to the state value though. This is because Functor has kind "* -> *", whereas "State" has kind "* -> * -> *", so the first type parameter needs to be fixed.

instance Applicative (State s) where
pure :: a -> State s a
pure a = State $ \st -> (a, st)

(<*>) :: State s (a -> b) -> State s a -> State s b
sf <*> sa = State $ \st -> let (f, st1) = runState sf st
(a, st2) = runState sa st1
in (f a, st2)


Applicative lets you put values into State, and to apply a stateful function to a stateful value: and thread through the state from left to right.

instance Monad (State s) where
(>>=) :: State s a -> (a -> State s b) -> State s b
sa >>= f = State $ \st -> let (a, st') = runState sa st
in runState (f a) st'


Monad lets you sequence stateful actions together.

We also want to be able to modify this internal state, in particular we want to be able to read the current state, and replace it with a new value:

get :: State s s
get = State $ \st -> (st, st)

put :: s -> State s ()
put s = State $ \_ -> ((), s)


Now a little example:

example :: State Int String
example = do
x <- get
put (x + 1)
y <- get
put (y + 1)

pure "hello world"

main :: IO ()
main = print $ runState example 0


This prints ("hello world",2).

>>

 No.12392

>>12385
Don't try to "understand" monads, because like many other abstracts constructs, they are -semantical- definitions. That means that they allow many implementations, which differ a lot in nature. It's like trying to define a "machine", it's not really useful.

In Haskell however they have a very practical side. You can see a progression.

- Type constructor : `F a` creates a context `F` with values of type a.
- Functor: You can apply functions inside this context.
 f :: a -> b => fmap f :: F a -> F b 

- Applicative: You can use in-context functions.
 f :: a -> b => F f :: F (a -> b) => (<*>) F f :: F a -> F b 

- Monad : You can apply functions with produces contexts inside contexts
 f :: a -> F b => (=<<) f :: F a -> F b 


Given this machinery, you can see their utility. But trying to reduce these concepts to a metaphor is just restricting their nature and utility.

>>

 No.12424

>>12360
>Anything abstract can be boiled down slowly to less abstract concepts.
Like with any programming concept, it's easier to describe how the thing *operates* than explaining what it actually *is*. Defining the concept of a "function" in a concrete and exact way is what gives you the whole field of denotational semantics. Anything less is metaphorical and dishonest.

You can however explain how to use functions, what a particular function does and even how to make your own. Same goes with monads: You use them with "do"-notation or the >>= operator, they often have a clearly defined interpretation as a style of effectful computation, and defining your own requires you to define a way to "put things into the monad" and to "flatten nested monads", which can mean different things depending on your particular case.

Of course, sometimes the metaphorical handwaving can be useful for beginners. Saying "functions are sort of like mathematical functions" at least gives somewhat of an intuition how to approach them. IMHO, the best metaphor for monads is that of a recipe for an effectful computation, even though it's certainly not applicable in all cases. Read some early (but not too early) papers and tutorials from the list in >>12363.



Delete Post [ ]
[ cyb / tech / λ / layer ] [ zzz / drg / lit / diy / art ] [ w / rpg / r ] [ q ] [ / ] [ popular / ???? / rules / radio / $$ / news ] [ volafile / uboa / sushi / LainTV / lewd ]