Week #6 Challenge: Haskell

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • 4

57 Replies - 11486 Views - Last Post: 01 June 2010 - 06:46 AM

#16 Raynes  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 611
  • View blog
  • Posts: 2,815
  • Joined: 05-January 09

Re: Week #6 Challenge: Haskell

Posted 11 February 2010 - 10:09 AM

View PostPaul-, on 10 February 2010 - 07:47 PM, said:

This was a challenge, no kidding. First, my openSUSE, although having several GB of software, it has no Haskell. I had to compile from sources, including installing missing libraries: what a pain. Then I struggled with the Haskell syntax...


I'm assuming you didn't build GHC from source, right? The Haskell Platform is the way to go these days, and it's usually dead simple to compile. Just need an easier way besides erroring out to let one know one needs a certain library.

MentalFloss said:

As it stands, the source code I've seen so far must be the closest thing to magical incantations I've ever seen regarding my understanding of programming.


Pure functional programming is pretty bizarre for a while, and certainly takes some effort to learn coming from OOP and imperative programming. However, the experience will Haskell will serve you very well in languages you already use. After you learn Haskell, you'll understand the benefits of functional programming, and ways to use it properly, and then you'll be able to take advantage of functional features in otherwise non-purely-but-still-functional languages like Scala, Clojure, C# (I hear it gets more functional all the time), and even marginally Python.

How is that for motivation? :p

My intention with this challenge and the Clojure challenge I hope is used in the future is to try to get you guys to see the beauty in functional programming, instead of viewing it as some bizarre paradigm that is completely useless in anything except academia.

One thing I will mention here that I didn't mention in the challenge is that the phrase "Haskell is purely functional" is very important. Purely functional, and just functional are different things. The reason Haskell is so difficult is at first is because you guys are all used to mutable state and mutations, and purely functional languages don't straight-up allow such things (though you can use IORefs and various other things to simulate mutable state). Other languages like Clojure for example aren't purely functional. It's a strongly functional language that gives up purity for practicality, but still doesn't directly allow you to mutate mutable state. You have to do so through refs and atoms and other concurrency primitives, but it's still easier to grok than the way Haskell does things.

What I'm trying to say with the very verbose paragraph above this one is this: if you have a bad experience this week, or in the future, with Haskell, don't give up on functional programming because of it. Haskell is pure, and that changes things significantly. If you like what you see, but don't think Haskell can give you what you want (it can, but it takes time and patience to learn how), there are other functional and inpure languages like Clojure and Scala (sorry, I like the JVM) that you could use as well.

Enjoy the rest of the week, and good job on your submissions guys. :)

This post has been edited by Raynes: 11 February 2010 - 10:21 AM

Was This Post Helpful? 0
  • +
  • -

#17 cgomez82  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 16-June 09

Re: Week #6 Challenge: Haskell

Posted 11 February 2010 - 12:40 PM

So this felt like learning how to ride a bike but instead of ever being successful and taking off the training wheels I just kept falling, scraping my knees and elbows while crying in the fetal position accepting that I will never be able to ride the Haskell bike.

Originally I wanted this to keep a balance that way a user could ideally play until their balanced had been spent. This example is more of a guessing game that rewards you by doubling your bet and nothing more. A bit lamer than I originally expected but I learned something nonetheless.

--Three Card Monte
module Main
	where
import IO
import Random
	
main = do

	putStrLn "Welcome to Three Card Monte."
	rand <- randomRIO (1::Int, 3)
	userPick rand
	
userPick rand = do
	putStrLn "How much do you want to bet?"
	playerBet <- getLine
	let pBet = read playerBet :: Int
	putStrLn "Please make your selection 1, 2, or 3"
	pick <- getLine
	let upick = read pick
	if upick == rand
		then do putStrLn "You win!"
			let winner = pBet * 2
			putStrLn "Balance is " 
			putStrLn $ show winner
		else do putStrLn "Loser"



Big thanks on the resources especially "YAHT" for the Random help.
Was This Post Helpful? 0
  • +
  • -

#18 Shane Hudson  Icon User is offline

  • D.I.C Technophile
  • member icon

Reputation: 343
  • View blog
  • Posts: 1,286
  • Joined: 06-December 09

Re: Week #6 Challenge: Haskell

Posted 11 February 2010 - 01:16 PM

Hmm, really struggling with this! I understand the maths functionality, as well as the boolean but making anything useful... not there yet. Hopefully I will have time to focus on it over the weekend!
Was This Post Helpful? 0
  • +
  • -

#19 Paul-  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 61
  • View blog
  • Posts: 260
  • Joined: 11-December 09

Re: Week #6 Challenge: Haskell

Posted 11 February 2010 - 02:42 PM

View PostRaynes, on 11 February 2010 - 09:09 AM, said:

View PostPaul-, on 10 February 2010 - 07:47 PM, said:

This was a challenge, no kidding. First, my openSUSE, although having several GB of software, it has no Haskell. I had to compile from sources, including installing missing libraries: what a pain. Then I struggled with the Haskell syntax...


I'm assuming you didn't build GHC from source, right? The Haskell Platform is the way to go these days, and it's usually dead simple to compile. Just need an easier way besides erroring out to let one know one needs a certain library.


That's exactly what happened. I had to go through several iterations to install all the libraries that the Haskell Platform required.
Was This Post Helpful? 0
  • +
  • -

#20 carltech  Icon User is offline

  • What did you call me?
  • member icon

Reputation: 28
  • View blog
  • Posts: 997
  • Joined: 19-October 07

Re: Week #6 Challenge: Haskell

Posted 12 February 2010 - 04:24 AM

I like how simple recursion is. I made a factorial function then found I didn't need the conditional statement.

fact :: Int -> Int 
fact x = if x > 1 then (x * fact (x - 1)) else 1'


or

fact :: Int -> Int
fact 1 = 1
fact x = x * fact (x - 1)

:hungry:

I like the concept of functional programming but some of the syntax is weird to me.
Although that could be because I just started learning Haskell yesterday. <_<

man am I a n00b at Haskell

This post has been edited by carltech: 12 February 2010 - 04:27 AM

Was This Post Helpful? 0
  • +
  • -

#21 carltech  Icon User is offline

  • What did you call me?
  • member icon

Reputation: 28
  • View blog
  • Posts: 997
  • Joined: 19-October 07

Re: Week #6 Challenge: Haskell

Posted 13 February 2010 - 08:33 AM

after reading some of the learnyouhaskell tutorial I found a recursion function that is remarkably similar to mine...

I feel like a fool as it took me like a couple of minutes to write mine thanks to trying to figure out the syntax

Then I went back a page and saw this
factorial :: Integer -> Integer  
factorial n = product [1..n]  
:stupid:

This post has been edited by carltech: 13 February 2010 - 08:38 AM

Was This Post Helpful? 0
  • +
  • -

#22 Raynes  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 611
  • View blog
  • Posts: 2,815
  • Joined: 05-January 09

Re: Week #6 Challenge: Haskell

Posted 13 February 2010 - 09:53 AM

The Haskell standard library is massive. It's difficult to not end up writing functions that are already written.
Was This Post Helpful? 0
  • +
  • -

#23 .Aaron  Icon User is offline

  • Rock, paper, scissors, lizard, Spock
  • member icon

Reputation: 62
  • View blog
  • Posts: 2,895
  • Joined: 04-August 09

Re: Week #6 Challenge: Haskell

Posted 13 February 2010 - 06:44 PM

Great idea for a challenge, Raynes. At first part of me agreed with the comment by MentalFloss about magical incantations (though think the tutorial I started with is partly to blame, after switching to a new one things went a bit better). It is quite a switch when you're use to OOP. The whole thing still feels pretty akward to me, but your right, its not really that bad.


Haven't managed much so far, just gets a few numbers from the user (the putStrLn 's explain what and why well enough..) and multiplies them all. Also matches the specific heat to a substance. If it happenes to be a substance who's specific heat I can still remember, anyway. Think this is going to be a language I'll stick with past just finishing this challenge, so I'll keep adding to it as I go.



main = do
  putStrLn "To determin the amount of energy needed to heat the substance, "
  putStrLn "enter the amount of the substance to be heated (in g) followed "
  putStrLn "by it's Specific heat (J/g *C), and finaly, the temperature by "
  putStrLn "which you want to heat it (in Celsius). "
  elemdata ←  getLine
  putStrLn $ "\n" ++ show ( checkelem ( words elemdata ))
  putStr $ "The amount of energy needed to heat your substance by " ++ words elemdata !! 2 ++ " degress Celsius is: \n"
  putStr $ show ( findjs (words elemdata)) ++ " Joules, and " ++ show ( findjs ( words elemdata ) / 4 ) 
  putStr " calories. \n \n"


findjs :: [String] →  Double
findjs (grms:c:ntemp:_) =
       grams * specificheat * chngintemp
       where grams = ( read grms :: Double )
             specificheat = ( read c :: Double )
             chngintemp = ( read ntemp :: Double )


checkelem :: [String] →  String
checkelem (grms:c:ntemp:_)
       | sp ≡ 4.184 = "Your substance is water."
       | sp ≡ 0.3851 = "Your substance is Copper."
       | sp ≡ 0.4521 = "Your substance is Iron."
       | sp ≡ 0.8372 = "Your substance is Glass."
       | sp ≡ 0.9000 = "Your substance is Aluminum."
       | otherwise = "Unknown substance."
       where sp = (read c ::Double)



Was This Post Helpful? 0
  • +
  • -

#24 Raynes  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 611
  • View blog
  • Posts: 2,815
  • Joined: 05-January 09

Re: Week #6 Challenge: Haskell

Posted 13 February 2010 - 08:36 PM

http://www.haskell.o...ary/013911.html

You can kill away some of those putStrLns. Good job, and I'm happy you're enjoying Haskell.
Was This Post Helpful? 0
  • +
  • -

#25 .Aaron  Icon User is offline

  • Rock, paper, scissors, lizard, Spock
  • member icon

Reputation: 62
  • View blog
  • Posts: 2,895
  • Joined: 04-August 09

Re: Week #6 Challenge: Haskell

Posted 13 February 2010 - 08:57 PM

Ah, ok. Thanks for link. Figured there had to be a better way to do it, but wasn't sure since Haskells pretty different. Nothing I've read yet has went over it.
Was This Post Helpful? 0
  • +
  • -

#26 erik.price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 485
  • View blog
  • Posts: 2,690
  • Joined: 18-December 08

Re: Week #6 Challenge: Haskell

Posted 13 February 2010 - 10:54 PM

Another painfully simple submission, Newton's method for calculating square root.

I've done it in a couple languages already, but never in a functional one (or recursively) so I suppose it's fitting

newtonSqrt' num guess epsilon = if abs guess * guess - num < epsilon
			then guess
			else
			newtonSqrt' num newGuess  epsilon
			where newGuess = guess - (guess * guess - num) / (2 * guess)

newtonSqrt :: Double -> Double
newtonSqrt num = do
		newtonSqrt' num 10  0.0000000001


I still suck at Haskell, so any pointers would be great :)

edit: Ack, the ' in newtonSqrt' messed up the syntax highlighting

This post has been edited by erik.price: 13 February 2010 - 10:55 PM

Was This Post Helpful? 0
  • +
  • -

#27 erik.price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 485
  • View blog
  • Posts: 2,690
  • Joined: 18-December 08

Re: Week #6 Challenge: Haskell

Posted 14 February 2010 - 08:18 PM

Another function that is already built in, and probably optimized a hell of a lot better, reverse a list
rev :: [a] -> [a]
rev [] = []
rev list = last list : rev (init list)


This was actually a bit annoying to write, I mixed up (++) and (:) and stupidly couldn't figure out the resulting error message.

This post has been edited by erik.price: 14 February 2010 - 11:58 PM

Was This Post Helpful? 0
  • +
  • -

#28 Raynes  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 611
  • View blog
  • Posts: 2,815
  • Joined: 05-January 09

Re: Week #6 Challenge: Haskell

Posted 14 February 2010 - 11:08 PM

View Posterik.price, on 14 February 2010 - 07:18 PM, said:

Another function that is already built in, and probably optimized a hell of a lot better, reverse a list
rev :: [a] -> [a]
rev [] = []
rev list = last list : reverse (init list)


This was actually a bit annoying to write, I mixed up (++) and (:) and stupidly couldn't figure out the resulting error message.


Reverse is actually implemented like this:
reverse = foldl (flip (:)/>) []
. I'm not sure if you realize it or not, but you actually used reverse to implement reverse. That is cheating!
Was This Post Helpful? 0
  • +
  • -

#29 erik.price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 485
  • View blog
  • Posts: 2,690
  • Joined: 18-December 08

Re: Week #6 Challenge: Haskell

Posted 14 February 2010 - 11:57 PM

Oops! I originally called the function 'rev' but wanted to see what would happen if I caused a naming conflict with the 'reverse' function in the Prelude, so I renamed everything to reverse. Guess I forgot to change one 'reverse' back into 'rev' :P
Was This Post Helpful? 0
  • +
  • -

#30 Raynes  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 611
  • View blog
  • Posts: 2,815
  • Joined: 05-January 09

Re: Week #6 Challenge: Haskell

Posted 15 February 2010 - 12:13 AM

View Posterik.price, on 14 February 2010 - 10:57 PM, said:

Oops! I originally called the function 'rev' but wanted to see what would happen if I caused a naming conflict with the 'reverse' function in the Prelude, so I renamed everything to reverse. Guess I forgot to change one 'reverse' back into 'rev' :P


Well, it's definitely inefficient, because init has to walk the list every time the function recurses. If possible, it's almost always a good idea to use a fold (foldl or foldr) in place of explicit recursion, and it's always best if you can just use standard library functions in place of recursion as a whole. So you should think of it like this: Standard library functions -> folds -> explicit recursion. Folds are made to generalize over a specific and common sort of recursion, which is "take an element of a list, modify an accumulator value based on that element of the list, rinse, repeat, profit?????".
Was This Post Helpful? 0
  • +
  • -

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • 4