• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Haskell

Status
Not open for further replies.
You decide to use functional languages because you prefer it, not because of speed.

If you ONLY want speed you will code Assembler, C or C++.

Actually counts for all programming languages. I decide to use Java not because of the speed, because it's easyer to work with Java instead of C or C++. Speed is NEVER the only aspect of a programming language.
 
You decide to use functional languages because you prefer it, not because of speed.

If you ONLY want speed you will code Assembler, C or C++.

Actualy you use them if you want good speed for easy implementation, this is specialy the case of parallizeable code. Because of function purity, making the code be parallizeable is a lot easier.
 
Actualy you use them if you want good speed for easy implementation, this is specialy the case of parallizeable code. Because of function purity, making the code be parallizeable is a lot easier.
Good point.

Well Rui. If you want pure speed and you know what you're doing, you can get the best speeds with C or C++ unless you are super pro / crazy and write everything in Assembler.
 
But isn't Assembly different for distinct processor architectures? If I wrote something in Assembly wouldn't I have to write distinct code for distinct machines?

By the way, I've got to deliver my first Programming Principles task next week and I wanted to make sure everything's okay. Does this function do what I think it does? Won't it block on generating the list?

Code:
evenDivisors n = take (n/2) [ x | x <- [2,4..], n 'mod' x == 0 ]

EDIT: GW suggestion
evenDivisors n = take (div n 2) [ x | x <- [2,4..], mod n x == 0 ]
 
Last edited:
Supposedly, Haskell will only generate a list that has as many elements as take() requires, instead of generating that endless list. Having no take function will actually make the generation infinite.

P.S. — I didn't use [2,4..n] because I think it'll yell at you if n < 4, and n should be a natural number.

P.P.S. — Isn't there a function that allows me to round up the value of take()? I think it'll crash if it receives a float instead of the expected int.
 
n / 2 is an error, since the division operator isn't defined for Integral types.
Use the div function.

In addition, I was right about the need for a bound since given an input with no even divisors, you will go to infinity and beyond (this also means you can drop the take).
 
Bind it = give it a name you can reference it with.

Though in JavaScript and Lua "_" is a legal variable name you can reference, so I wouldn't be surprised if it's the same way in Haskell.
People just use it to show that they don't care about that specific value.

E.g. in a function that checks the length of a list by iterating over it, you really don't care about the list elements, only the number of iterations, so you'd use _ instead of a meaningful name.
 
Assembler is for slowpokes, GPU parallelism is the way to go! (this is both a joke and reality, and a joke on reality, and a joke on YOU, because who gives a damn about speed (no DSG, don't start it here too)).

Can you please stop bullshitting interesting threads with your gpu shit? Its unrelated but even if this was a gpu computing thread it would still be boring.

Functional languages are VERY interesting for parallelism because its functions are stateless (unlike functions in imperative languages). That means the result of a function depends only on its arguments and not on the time or order which it is executed in.

However what GPUs do is very simple SIMD parallelism which covers only a very small part of parallel computing. Also its boring, BORING AS FUCK.
 
It's just an IDE(codeblocks). I've never tried haskell but it looks good. What do you need to run haskell codes? I mean does it need something like java (JRE)? Anyways, thanks.
 
Thanks, I also found some online interpreters, looks cool, trying the beginner tutorials, thanks Rui. :D
 
Tail-recursion means, that the last statement is only the recursive call. Usually the interpreter/compiler makes a normal loop out of it and you don't need that much space on the stack for all the function calls. Example:
func fak(n)
if n <= 1 return 1
else return n * fak(n-1)

this isn't tail recursion since the last statement (n * fak(n-1)) also includes the multiplication. To prevent this you can do it like this:

func fak(n)
return fak-rek(n, 1)

func fak-rek(n, res)
if n <= 1 return res
else return fak-rek(n - 1, res * n)
 
Well pretty much tail-recursion means that all recursive calls are at the end of a function's execution path and that are undependant of any operation in that executation path.

Examples of factorial in haskell:
Code:
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * (factorial n-1)

-- tail recursive
factorial :: Int -> Int
factorial 0 = 1
factorial n = factorialAux n 1
    where
        factorialAux 1 v = v
        factorialAux n v = factorialAux (n-1) (v*n)

As you see, i just pass the result as an argument, this way I can make sure the tail recursive property is kept. The compiler will optimize that into a simple fast loop, rather than a recursive function. If you look at the tail recursive call, the current argument frame is no longer needed, therefore the space used for them can be recycled instead of creating a new frame in the stack.

Here's how it would look using prelude functions
Code:
-- using prelude functions
factorial :: Int -> Int
factorial 0 = 1
factorial n = product [1..n]

the reason why it's good practice to use prelude functions and high order functions in haskell, has to do with the fact that all prelude functions are very optimized for the task. It also has to do with some compiler optimizations.
 
Hey, nice that you're here BlinkBoy, I'm having some trouble with this:

Code:
foldMatrizParaLista xs = nub . ( foldr (\y acc -> (fst(y)):acc) [] xs )

Basically, the function is supposed to take a list of tuples and build another list with only the first element of each tuple, eliminating repetitions, of course. The compiler says this:

PHP:
Couldn't match expected type `a -> [a1]' with actual type `[a2]'
Relevant bindings include
foldMatrizParaLista :: [(a2, b)] -> a -> [a1]
(bound at

I've got a much easier way to do this, but we were ordered to resort to foldl/r.
 
Hey, nice that you're here BlinkBoy, I'm having some trouble with this:

Code:
foldMatrizParaLista xs = nub . ( foldr (\y acc -> (fst(y)):acc) [] xs )

Basically, the function is supposed to take a list of tuples and build another list with only the first element of each tuple, eliminating repetitions, of course. The compiler says this:

PHP:
Couldn't match expected type `a -> [a1]' with actual type `[a2]'
Relevant bindings include
foldMatrizParaLista :: [(a2, b)] -> a -> [a1]
(bound at

I've got a much easier way to do this, but we were ordered to resort to foldl/r.

The use of the dot is the problem. The dot is function composition, so it expects a function on the right hand side of the dot (expected type `a -> [a1]'), but you give it a list instead (actual type `[a2]').

You could remove the dot or remove the last argument:

Code:
foldMatrizParaLista1 :: Eq a => [(a,b)] -> [a]
foldMatrizParaLista1 xs = nub (foldr (\y acc -> (fst y):acc) [] xs)

foldMatrizParaLista2 :: Eq a => [(a,b)] -> [a]
foldMatrizParaLista2 = nub . (foldr (\y acc -> (fst y):acc) [])

foldMatrizParaLista3 :: Eq a => [(a,b)] -> [a]
foldMatrizParaLista3 = nub . (foldr ((:) . fst) [])

foldMatrizParaLista4 :: Eq a => [(a,b)] -> [a]
foldMatrizParaLista4 = nub . (map fst)
 
Duh, I placed that dot because my initial idea was different, then I forgot to remove it. Then compilers could actually be a little more friendly. If someone ever makes a compiler in 1 programming language that actually tells you what's wrong with your script... T.T

Thanks so much!

EDIT: Hold on, are you sure the dot in the second function is gonna work?
 
codeblocks, visual studio, GCC and many more will say whats wrong with the script and also the line the error is in
however I think neither of those support(maybe GCC, it supports even brainfuck) Haskel
while GCC is mostly for linux(MinGW has windows version of it) linux, it will say in console even possition of not matching character
 
I have another problem. Usually, the '$' sign appears inbetween parameters, but I have no idea how to do it in this case. I want the arguments taken to be associated to f.
Right now it yells at me because of it thinks I'm associating more arguments to length and not passing the arguments to f, which takes the same types as g.
Code:
g = length f

Every variation I've tried returns an error as well:
Code:
g $ = length f  -- Input error '='
g = length $ f
g = $ length f  -- Parse error input '$'

This is to make use of currying and avoid the following:
Code:
g xs x = length ( f xs x )     -- Eliminating those xs and x on both sides makes the function that much cleaner
 
Do not get too obsessed with point free style ;) It can get quite unreadable sometimes. For example here you could probably use this:

Code:
g = ((.) . (.)) length f

But who wants to read that?

And the $ operator is really useless as (f x) means the same as (f $ x). It is only used to avoid parenthesis.
 
Do not get too obsessed with point free style ;) It can get quite unreadable sometimes. For example here you could probably use this:

Code:
g = ((.) . (.)) length f

But who wants to read that?

And the $ operator is really useless as (f x) means the same as (f $ x). It is only used to avoid parenthesis.

Well I use $ a lot to make my code more readable sometimes.

the eager operator $! on the other hand is quite more usefull.
 
Could somebody explain to me what that ((.) . (.)) does though?

So (.) is the function composition operator. It is defined like this:

Code:
(.)    :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)

So (f . g) x is the same as (f (g x)).

Knowing this you can rewrite the expression ((.).(.)) as follows:

Code:
((.) . (.))
-- remove infix notation
((.) (.) (.))
-- replace (.) with its definition
((\f g x -> f (g x)) (\f g x -> f (g x)) (\f g x -> f (g x)))
-- rename variables
((\f1 g1 x1 -> f1 (g1 x1)) (\f2 g2 x2 -> f2 (g2 x2)) (\f3 g3 x3 -> f3 (g3 x3)))
-- inline parameter f1
(\g1 x1 -> (\f2 g2 x2 -> f2 (g2 x2)) (g1 x1))  (\f3 g3 x3 -> f3 (g3 x3))
-- inline parameter g1
(\x1 -> (\f2 g2 x2 -> f2 (g2 x2)) ((\f3 g3 x3 -> f3 (g3 x3)) x1))
-- inline parameter f3
(\x1 -> (\f2 g2 x2 -> f2 (g2 x2)) (\g3 x3 -> x1 (g3 x3)))
-- inline parameter f2
(\x1 -> (\g2 x2 -> (\g3 x3 -> x1 (g3 x3)) (g2 x2)))
-- inline parameter g3
(\x1 -> (\g2 x2 -> (\x3 -> x1 (g2 x2 x3))))
-- rewrite lambda
(\x1 g2 x2 -> (\x3 -> x1 (g2 x2 x3)))
-- rewrite lambda
(\x1 g2 x2 x3 -> (x1 (g2 x2 x3)))
-- rewrite lambda
(\x1 g2 x2 x3 -> x1 (g2 x2 x3))
-- rename parameters
(\f g x y -> f (g x y))

I think the last expression is a bit clearer.
 
I'm having a new problem. The following function f is correct, but Haskell doesn't appear to like the signature (I've put it as a comment)?

I'm still trying to understand what's the order of evaluation of ((.) . (.)) though =s

Code:
suc :: Eq a => [(a,a)] -> a -> [a]
adj :: Eq a => [(a,a)] -> [a]

--f :: Eq a => [(a,a)] -> [(a,[a])]
f graph = [ (x,y) | x <- (adj graph) , y <- ( suc graph x ) ]
 
Shouldn't the range iterate through each possible x and y? Actually the y is really supposed to be a list, now I'm in doubt how to do that. I want every pair to have one of each x of the list and y to be the list that comes from suc.

Blink, you can't explain the order of evaluation of ((.) . (.))? I'm really curious about that, the demonstration is weird, I don't quite follow from the first inline onwards. peq? >< Where did you learn this trick?
 
Yay, this thread is still running!
Hmm $! doesn't appear on Learn You A Haskell for Great Good!, I guess I have to search elsewhere?
It's defined in terms of seq.

f $! x = x seq f x

seq is the simplest way to introduce strictness to your program. seq takes two arguments of any type and returns the second. It's also magically strict in its first argument. So,
⊥ `seq` b = ⊥
a `seq` b = b

Basically x `seq` y will evaluate x before it considers y.

You can use ($!) pretty much like you do the ordinary function application operator.
f x = g $! h $! x

which will evaluate x, h x and apply g to the result, in that order. If you want to read more, there should be plenty of info on the Haskell wiki.
 
Blink, you can't explain the order of evaluation of ((.) . (.))?

The order usually does not matter in Haskell since there are no side-effects. So you can usually evaluate a Haskell expression as you would simplify a mathematical expression.

I'm really curious about that, the demonstration is weird, I don't quite follow from the first inline onwards. peq? >< Where did you learn this trick?

I have seen it here: http://stackoverflow.com/questions/5821089/haskell-function-composition-operator-of-type-cd-abc-abd

Maybe you could also write it as "(length .) . f", which is a bit more readable, but I still would not write something like that.

I don't know how to explain it any better than in my last post and I don't think there is a way to read this nicely. That's why it should not be used ;)

One problem with Haskell is that people actually use stuff like this which makes some code very hard to read, if you have not seen a certain operator or pattern.
 
Status
Not open for further replies.
Back
Top