I've read through some Haskell material before and tried following tutorials, but I always end up dropping it because I can't think of anything for which I would use it.
I have no problem with functional and functional-esque programming (Erlang, Common Lisp, etc.), but I just can't come up with anything to do in Haskell. :(
EDIT:
Thanks for the great suggestions, everyone! I think I'll do some crpyo-based maths work in Haskell since that is what holds my interest at the moment. :-)
What do you normally program? Do that, but in Haskell. It's a general-purpose programming language, and there are plenty of libraries to help you in any area.
http://jonathan.tang.name/files/scheme_in_48/tutorial/overvi...
Lets define a simple type, `Maybe', which can store either a value or an absence of value:
data Maybe a = Just a | Nothing
deriving (Show)
And define a function which compares a number against a limit, and returns `Nothing' if the value is out of range: clamp :: Ord a => a -> a -> Maybe a
clamp limit x = if x > limit then Nothing else Just x
Easy enough. Now, how should the number be compared against multiple limits?One way is to just brute-force it:
multiclamp :: Ord a => a -> a -> a -> Maybe a
multiclamp lim1 lim2 x = case clamp lim1 x of
Nothing -> Nothing
Just x' -> clamp lim2 x'
But this is ugly. Lets use monads to simplify it.First, take a look at the core Monad operations. I'm going to use `build' and `bind' instead of `return' and `>>=', because they're probably more familiar to most readers.
class Monad m where
build :: a -> m a
bind :: m a -> (a -> m b) -> m b
Next, we'll define an instance of the `Monad' typeclass for `Maybe'. It will use the same semantics as the `multiclamp' example -- that is, if the first test returns `Nothing', the entire computation will return `Nothing': instance Monad Maybe where
build x = Just x
bind Nothing _ = Nothing
bind (Just x) f = f x
Using this definition, `multiclamp' can be written thus: multiclamp2 :: Ord a => a -> a -> a -> Maybe a
multiclamp2 lim1 lim2 x = bind
(clamp lim1 x)
(\x' -> clamp lim2 x')
Although ugly, this notation is sufficiently generic that the compiler can generate it from an imperative notation. Lets look at two more examples. First, `multiclamp2' written using "real" monads. Notice that this is exactly the same as before, except `bind' is an operator named `>>=': multiclamp3 :: Ord a => a -> a -> a -> Maybe a
multiclamp3 lim1 lim2 x =
(clamp lim1 x) >>=
(\x' -> clamp lim2 x')
And finally, using the imperative-style `do' notation. Note that although this is imperative, it is not impure -- this is semantically equal to `multiclamp3': multiclamp4 :: Ord a => a -> a -> a -> Maybe a
multiclamp4 lim1 lim2 x = do
x' <- clamp lim1 x
clamp lim2 x'
This is, obviously, a superficial example -- you'd never see such verbose code in code written by an experienced programmer. But the verbosity helps to visualize what the compiler is doing.For completeness, here's a "cleaner" version, which takes advantage of currying and the combinator `.':
multiclamp5 :: Ord a => a -> a -> a -> Maybe a
multiclamp5 lim1 lim2 = (clamp lim2 =<<) . clamp lim1For me at least, the mathematics line-noise is a bigger issue, and it made more sense once I ignored it. As a programming construct, monads seem quite understandable to me, even clever. But many of the explanations, especially earlier ones, started out with a type-theoretic explanation with links to category theory...
In particular, I was under the misimpression for years, because of it being presented that way, that monads were essentially of interest only for people who were hung up on type-checking: that they were a solution to how to make the type-checking go through on a certain class of problems, by lifting an underlying type into the Monadic type and getting it back out again. As someone who mainly uses dynamically typed languages, this didn't seem of interest, since in Lisp, I don't care if the type-checking goes through or not. It was probably years later that I figured out they had some non-type-related programming benefit.
http://lamp.epfl.ch/~emir/bqbase/2005/01/20/monad.html has an explanation from scala's perspective. I can understand the first part when the author describes a monad as an object with a polymorphic type, a map function, a flatten function, and a singleton constructor function. Everything they said beyond that goes right over my head.
multiclamp5 :: Ord a => a -> a -> a -> Maybe a
multiclamp5 lim1 lim2 = Kleisli (clamp lim1) >>> Kleisli (clamp lim2)
be even cleaner? The composition looks more obvious to me that way (plus, I like the symmetry).That's just computer science -- a bunch of CS stuff is easier to express in Haskell, so we do, but it might need some background.
> here's how to do in Haskell the stuff you already know how to do in Ruby
Try a different tutorial. Maybe: Real World Haskell?
I'll be back to this site in a few weeks to check for progress...
Type Haskell expressions in here.
> let x = 10
not an expression: `let x = 10'
I understand that mueval has this limitation too? It's more defensible in the irc context that "state" would be disallowed. Here, it's just crippling.I don't need the mtl stuff, but being able to define a basic function would be nice!
http://codepad.org/ will run full programs for you ... I guess that'll continue to be my tool of choice for online Haskell prototyping.
Still, this project does seem promising.
To be honest, if you're at the point where you want that sort of thing, I'd generally suggest simply downloading ghci. ISTM that all these "try it online" things are good for are making the decision of whether you want to bother with that step. (Perhaps I'm spoiled on Linux where downloading GHC or Ruby is hardly any harder than visiting a web page anyhow.)
> let x = 10 ; y = 5 ; in x + y
=> 15
:: (Num t) => tPretty cool app. A tutorial to go along with it would do wonders.
:m + Data.List intersperse '.' "hello"
And anything else you'd need if you want to use stuff other than just the Prelude.
> reverse [1..]
Time limit exceeded:m + Data.List intersperse '.' "hello"
And anything else you'd need if you want to use stuff other than just the Prelude.
:m + Data.List intersperse '.' "hello"
And anything else you'd need if you want to use stuff other than just the Prelude.
:m + Data.List intersperse '.' "hello"
And anything else you'd need if you want to use stuff other than just the Prelude.