[Haskell-cafe] Re: Learning about Programming Languages
(specifically Haskell)
Kyle Murphy
orclev at gmail.com
Mon May 3 11:17:58 EDT 2010
Reasons to learn Haskell include:
Lazy evaluation can make some kinds of algorithms possible to implement that
aren't possible to implement in other languages (without modification to the
algorithm).
Strict type system allows for a maximum number of programming errors to be
caught at compile time.
Functional design makes designing for concurrency and parallelism simpler
than in procedural or OO designs.
Clear differentiation of impure code helps to isolate points of failure and
to make the programmer more aware of possible side effects.
Knowledge of high order functions can provide the programmer with unique
ways of solving certain problems, even in non-functional languages.
Excellent Foreign Function Interface makes integration with existing
libraries relatively painless (compared with many other languages).
There are probably other reasons I'm not even aware of as I'm still a
beginner myself, but to me those are some of the most important.
The program you provided seems like a poor example to demonstrate the
language as it uses some very hard to follow logic for someone not familiar
with the language. Furthmore the results can not be easily explained nor
reasoned about simply (mostly due to the repeated application of id and
toggle instances to the same list as foldl runs). Nevertheless I've
attempted to provide what comments I can, although I'm sure someone can do
better than me and I might have made a mistake somewhere.
--- Begin Code ---
{- This declares a new type, Door, two new constructors for the Door type,
Open, and Closed, and tells the compiler to make Door an instance of the
Show class which provides the function show which can be used to convert
something into a String. I.E. show :: Door -> String -}
data *Door* = *Open* | *Closed* deriving *Show **
*
toggle :: Door -> Door
toggle *Open* = *Closed *-- New function to convert a Open Door to a Close
Door.
toggle *Closed* = *Open*
{- I broke this line down for easier understanding. This line takes two
lists and combines them using the ($) operator. The first list is provided
by converter, the second list is implicit as can be seen by the function
signature provided below and consists of a list of Doors. In other words, it
takes the function in the converter list, and applies it to the Door from
the last argument to the function to produce a new list of Door objects. The
list this produces can be thought of as looking something like the following
when called with 3 for example:
[(id $ Door), (id $ Door), (id $ Door), (toggle $ Door), (id $ Door), (id $
Door)...]
-}
pass :: Int -> [Door] -> [Door]
pass k = zipWith ($) converter
where
converter :: [Door -> Door]
{- This produces a list of functions from Door to Door, it produces
k id functions, one toggle function, and then repeats. id just returns
whatever it's given. -}
converter = cycle $ replicate k *id* ++ [toggle]
{- this creates two lists, one n long of Closed instances, and one from 0 to
n. flip pass reverses the order of arguments to pass so that instead of
taking a number and a list of Doors it instead takes a list of Doors and a
number. foldl takes one number from the list, the list of Closed Door
instances if this is the first time through, or the result of the last run,
and passes them both to pass. -}
run :: Int -> [Door]
run n = foldl (flip pass) (replicate n *Closed*) [0..n]
main = print $ run 100
--- End Code ---
-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.
On Mon, May 3, 2010 at 06:43, Rafael Gustavo da Cunha Pereira Pinto <
RafaelGCPP.Linux at gmail.com> wrote:
> If you are running from GHCi, just type run 100 at the prompt..
>
> If you intend to compile it, you have to add
>
> main = print $ run 100
>
> The compiler adds a call to main::IO (), which is intended to be the main
> entry point of your code.
>
> We need to add print, as run has type
>
> run::Int->[Door]
>
> so run 100 has type [Door].
>
> print is
>
> print::(Show a) => a -> IO ()
>
> The IO () stands for an empty IO monad, which is the black magic of
> haskell, intended to separate pure code from I/O side-effects...
>
>
>
>
> On Mon, May 3, 2010 at 06:31, Samuel Williams <
> space.ship.traveller at gmail.com> wrote:
>
>> Also, one more thing - if someone could write some comments to go along
>> with the source code that explain what it is doing, that would be really
>> helpful. I can see the general structure, but I don't know the ins and outs
>> of Haskell. If someone could augment the example with comments explaining
>> what the functions do that would be great!
>>
>> data *Door* = *Open* | *Closed* deriving *Show*
>>
>>
>> toggle *Open* = *Closed*
>> toggle *Closed* = *Open*
>>
>>
>> pass k = zipWith ($) (cycle $ replicate k *id* ++ [toggle])
>>
>>
>> run n = foldl (flip pass) (replicate n *Closed*) [0..n]
>>
>> Do I need to add run 100 to the end of the example for it to actually do
>> something?
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
>
>
> --
> Rafael Gustavo da Cunha Pereira Pinto
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100503/2cba9c42/attachment.html
More information about the Haskell-Cafe
mailing list