From russ.abbott at gmail.com Fri Jul 1 04:17:22 2016 From: russ.abbott at gmail.com (Russ Abbott) Date: Fri, 01 Jul 2016 04:17:22 +0000 Subject: [Haskell-beginners] Problem with installing GHCi 8.0.1 Message-ID: I downloaded GHCi 8.0.1 for Windows. Since I don't have administrator privileges I repeatedly clicked no when asked if I wanted to stop and restart with elevated privileges. Eventually it installed (in a folder on the desktop). The next step tells me to change some lines in the cabal user-config file. I followed the instructions to find that file, but all I got was an html file, which didn't seem right. I looked manually in multiple directories, but nothing seemed like the right file. Would someone help me find the file that needs to be changed. Also, WinGHCi does not appear in my start menu. Should it appear there by this point? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hjgtuyl at chello.nl Fri Jul 1 11:26:14 2016 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Fri, 01 Jul 2016 13:26:14 +0200 Subject: [Haskell-beginners] Problem with installing GHCi 8.0.1 In-Reply-To: References: Message-ID: On Fri, 01 Jul 2016 06:17:22 +0200, Russ Abbott wrote: > I downloaded GHCi 8.0.1 for Windows. Since I don't have administrator > privileges I repeatedly clicked no when asked if I wanted to stop and > restart with elevated privileges. Eventually it installed (in a folder on > the desktop). The next step tells me to change some lines in the cabal > user-config file. I followed the instructions to find that file, but > all I > got was an html file, which didn't seem right. I looked manually in > multiple directories, but nothing seemed like the right file. Would > someone help me find the file that needs to be changed. Searching for cabal config windows lead me to https://wiki.haskell.org/Cabal-Install#The_cabal-install_configuration_file which tells me that the config file is %appdata%\cabal\config That file should be created during installation, but you can create it yourself if necessary. > Also, WinGHCi does not appear in my start menu. Should it appear there by > this point? That is not done automatically; you can do it by right clicking on winghci.exe and selecting the proper option from the menu that appears. Regards, Henk-Jan van Tuyl -- Folding at home What if you could share your unused computer power to help find a cure? In just 5 minutes you can join the world's biggest networked computer and get us closer sooner. Watch the video. http://folding.stanford.edu/ http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html Haskell programming -- From russ.abbott at gmail.com Fri Jul 1 15:52:25 2016 From: russ.abbott at gmail.com (Russ Abbott) Date: Fri, 01 Jul 2016 15:52:25 +0000 Subject: [Haskell-beginners] Problem with installing GHCi 8.0.1 In-Reply-To: References: Message-ID: Sorry to be so dense, but how do you run the portable install option. After downloading the "Minimal platform I have a .exe installer file. When I run it, it doesn't offer a portable install option. What am I doing wrong? Thanks. On Fri, Jul 1, 2016 at 4:26 AM Henk-Jan van Tuyl wrote: > On Fri, 01 Jul 2016 06:17:22 +0200, Russ Abbott > wrote: > > > I downloaded GHCi 8.0.1 for Windows. Since I don't have administrator > > privileges I repeatedly clicked no when asked if I wanted to stop and > > restart with elevated privileges. Eventually it installed (in a folder on > > the desktop). The next step tells me to change some lines in the cabal > > user-config file. I followed the instructions to find that file, but > > all I > > got was an html file, which didn't seem right. I looked manually in > > multiple directories, but nothing seemed like the right file. Would > > someone help me find the file that needs to be changed. > > Searching for > cabal config windows > lead me to > > https://wiki.haskell.org/Cabal-Install#The_cabal-install_configuration_file > which tells me that the config file is > %appdata%\cabal\config > That file should be created during installation, but you can create it > yourself if necessary. > > > Also, WinGHCi does not appear in my start menu. Should it appear there by > > this point? > > That is not done automatically; you can do it by right clicking on > winghci.exe and selecting the proper option from the menu that appears. > > Regards, > Henk-Jan van Tuyl > > > -- > Folding at home > What if you could share your unused computer power to help find a cure? In > just 5 minutes you can join the world's biggest networked computer and get > us closer sooner. Watch the video. > http://folding.stanford.edu/ > > > http://Van.Tuyl.eu/ > http://members.chello.nl/hjgtuyl/tourdemonad.html > Haskell programming > -- > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From russ.abbott at gmail.com Sat Jul 2 01:41:56 2016 From: russ.abbott at gmail.com (Russ Abbott) Date: Sat, 02 Jul 2016 01:41:56 +0000 Subject: [Haskell-beginners] Problem with numeric types Message-ID: I'm trying to define primes using just list comprehension. The following works. Prelude> odds = [3, 5..] Prelude> primes = 2 : [p | p <- odds, null [d | d <- take (p `div` 4) odds, p `mod` d == 0]] But when I replace "take (p `div` 4)" with takeWhile (<=(sqrt p)) as in Prelude> primes' = 2 : [p | p <- odds, null [d | d <- (takeWhile (<=(sqrt p)) odds), p `mod` d == 0]] I get no error message on entering the statement, but when I run Prelude> take 8 primes' I get an error message that I can't understand. :23:1: error: • Ambiguous type variable ‘a0’ arising from a use of ‘it’ prevents the constraint ‘(Floating a0)’ from being solved. Probable fix: use a type annotation to specify what ‘a0’ should be. These potential instances exist: instance Floating Double -- Defined in ‘GHC.Float’ instance Floating Float -- Defined in ‘GHC.Float’ • In the first argument of ‘print’, namely ‘it’ In a stmt of an interactive GHCi command: print it I tried using (ceiling (sqrt p)), and I tried to explicitly declare it an Int, but neither of those helped. I'd appreciate some help. Thanks. P.S. The following runs fine. Prelude> takeWhile (<= (sqrt 99)) odds So I'm completely stumped. -------------- next part -------------- An HTML attachment was scrubbed... URL: From toad3k at gmail.com Sat Jul 2 06:09:27 2016 From: toad3k at gmail.com (David McBride) Date: Sat, 2 Jul 2016 02:09:27 -0400 Subject: [Haskell-beginners] Problem with numeric types In-Reply-To: References: Message-ID: Because mod :: Integral a => a -> a -> a and sqrt :: Floating a => a -> a, the final type of primes' ends up being :: (Floating a, Integral a) => [a], which doesn't work very well obviously. The easiest solution is to try let primes' = 2 : [p | p <- odds, null [d | d <- (takeWhile (<=ceiling (sqrt (fromInteger p))) odds), p `mod` d == 0]] You can make your own sqrt if you want to clean it up. let isqrt = ceiling . sqrt . fromInteger On Fri, Jul 1, 2016 at 9:41 PM, Russ Abbott wrote: > I'm trying to define primes using just list comprehension. The following > works. > > Prelude> odds = [3, 5..] > > Prelude> primes = 2 : [p | p <- odds, null [d | d <- take (p `div` 4) > odds, p `mod` d == 0]] > > > But when I replace "take (p `div` 4)" with takeWhile (<=(sqrt p)) > as in > > Prelude> primes' = 2 : [p | p <- odds, null [d | d <- (takeWhile (<=(sqrt > p)) odds), p `mod` d == 0]] > > I get no error message on entering the statement, but when I run > > Prelude> take 8 primes' > > I get an error message that I can't understand. > > :23:1: error: > • Ambiguous type variable ‘a0’ arising from a use of ‘it’ > prevents the constraint ‘(Floating a0)’ from being solved. > Probable fix: use a type annotation to specify what ‘a0’ should be. > These potential instances exist: > instance Floating Double -- Defined in ‘GHC.Float’ > instance Floating Float -- Defined in ‘GHC.Float’ > • In the first argument of ‘print’, namely ‘it’ > In a stmt of an interactive GHCi command: print it > > I tried using (ceiling (sqrt p)), and I tried to explicitly declare it an > Int, but neither of those helped. > > I'd appreciate some help. > > Thanks. > > P.S. The following runs fine. > > Prelude> takeWhile (<= (sqrt 99)) odds > > So I'm completely stumped. > > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From twashing at gmail.com Sun Jul 3 18:27:31 2016 From: twashing at gmail.com (Timothy Washington) Date: Sun, 3 Jul 2016 11:27:31 -0700 Subject: [Haskell-beginners] Howto reverse a Data.Array In-Reply-To: References: Message-ID: Hmm, this is very helpful - didn't know it existed. Thanks very much, I'll check it out! Tim On Thu, Jun 23, 2016 at 7:41 AM, David McBride wrote: > The problem isn't with array, but rather your index. Ix instances are > always sorted in ascending order, as you might imagine. You can however, > use your own index in arrays and they can be indexed in whatever order you > like. > > > {-# LANGUAGE GeneralizedNewtypeDeriving #-} > > import Data.Array > import Data.Ix > > newtype MyIx = MyIx Int deriving (Eq, Num, Show) > > instance Ord MyIx where > compare (MyIx a) (MyIx b) = > case compare a b of > LT -> GT > GT -> LT > EQ -> EQ > > instance Ix MyIx where > range (MyIx a, MyIx b) = map MyIx $ reverse [b..a] > index (MyIx a, MyIx b) (MyIx c) = a - c > inRange (MyIx a, MyIx b) (MyIx c) = c <= a && c >= b > > blah :: Array MyIx Char > blah = array (3,0) [(0,'a'),(1,'b'),(2,'c'),(3,'d')] > > Warning: I only very lightly tested the above code. > > You can mix your index and normal indexes to get the row / col ordering > you are hoping for. > > blah2 :: [((MyIx, Int), Char)] -> Array (MyIx, Int) Char > blah2 = array ((3,0),(0,3)) > > Finally, if you are really looking for something that is designed to be a > matrix, you might try one of several libraries that are out there, like > hmatrix. > > Hopefully this helps. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fordforox at gmail.com Mon Jul 4 07:43:41 2016 From: fordforox at gmail.com (OxFord) Date: Mon, 4 Jul 2016 09:43:41 +0200 Subject: [Haskell-beginners] Preorder function application Message-ID: Hello, why Haskell doesn't apply functions in preorder? e.g. f x = x max 1 f 2 > 2 max f 1 f 2 > 2 max max f 1 f 2 f 3 > 3 f f f f f f f f f f f 1 > 1 Thus you would need to put the arguments into brackets only when you want to partially apply that function. Is the current method more readable or error prone? King regards, Ford -------------- next part -------------- An HTML attachment was scrubbed... URL: From tanuki at gmail.com Mon Jul 4 11:20:32 2016 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Mon, 4 Jul 2016 04:20:32 -0700 Subject: [Haskell-beginners] Preorder function application In-Reply-To: References: Message-ID: If I understand correctly, you're asking why function application is left-associative rather than right-associative. With currying and first-class functions, right-association doesn't really work well. It's not obvious with a highly-constrained function like "max", but in practice most Haskell functions get composed and applied with other functions; real data only matters at the endpoints. For a reasonably simple example, consider the interaction between a couple of other Prelude functions: map :: (a -> b) -> [a] -> [b] const :: a -> b -> a Since (b -> a) is a type all by itself, it fits into a type variable for other functions; that is, "const" is an (a -> b) for the purposes of filling the first argument of "map". Applying this gets: map const :: [a] -> [b -> a] This takes a list of values, and returns a list of functions. So considering the type of "map const", which of the following behaviors seems more appropriate: > :t (map const) [1,2,3] map const [1,2,3] :: Num a => [b -> a] > :t map (const [1,2,3]) map (const [1,2,3]) :: Num a => [b] -> [[a]] Haskell chooses the first option, because giving an argument [a] to an expression whose type is currently [a] -> [b -> a] should probably return [b -> a]. On Mon, Jul 4, 2016 at 12:43 AM, OxFord wrote: > Hello, > > why Haskell doesn't apply functions in preorder? > e.g. > > f x = x > > max 1 f 2 > > 2 > max f 1 f 2 > > 2 > max max f 1 f 2 f 3 > > 3 > f f f f f f f f f f f 1 > > 1 > > > Thus you would need to put the arguments into brackets only when you want > to partially apply that function. > > > Is the current method more readable or error prone? > > King regards, > > Ford > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fordforox at gmail.com Wed Jul 6 16:04:57 2016 From: fordforox at gmail.com (OxFord) Date: Wed, 6 Jul 2016 18:04:57 +0200 Subject: [Haskell-beginners] Polymorphism ad hoc Message-ID: Hello, why does haskell support only parametric polymorphism? Is it because ad hoc p. || multiple dispatch is bad in general? King Regards, Ford -------------- next part -------------- An HTML attachment was scrubbed... URL: From nrujac at gmail.com Wed Jul 6 16:19:37 2016 From: nrujac at gmail.com (Arjun Comar) Date: Wed, 06 Jul 2016 16:19:37 +0000 Subject: [Haskell-beginners] Polymorphism ad hoc In-Reply-To: References: Message-ID: Hi Ford, Haskell does support ad-hoc polymorphism via type classes. In short, class Foo a where -- type declarations for related sets of functions that are polymorphic in a go here instance Foo Int where -- function definitions with a specialized to Int go here. The Show class is probably a fairly simple example you can play with in ghci. data Test = Test instance Show Test where -- show :: Test -> String show t = "Hello World" Thanks, Arjun On Wed, Jul 6, 2016 at 12:05 PM OxFord wrote: > Hello, > > why does haskell support only parametric polymorphism? > > Is it because ad hoc p. || multiple dispatch is bad in general? > > > King Regards, > > Ford > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From masat.semih at gmail.com Thu Jul 7 00:43:42 2016 From: masat.semih at gmail.com (Semih Masat) Date: Thu, 7 Jul 2016 03:43:42 +0300 Subject: [Haskell-beginners] Case vs Guards. I still don't know what is the difference Message-ID: Hello, I am new to Haskell and trying to learn it with learnyouahaskell.com and Pluralsight Haskell course. And i have a very noob question. I understand that *if .. else* is just a syntactic sugar over *case. *But what about guards then ? Are guards also *case *in different syntax ? Or vice versa ? Like with an example. anyEven nums | (length (removeOdd nums)) > 0 = True | otherwise = False anyEven' nums = case (removeOdd nums) of [] -> False (x:xs) -> True I can do the same thing with both of them. As i understand the only different thing is, with *case *i can manipulate the parameter (like here in the example i used removeOdd) and can use the manipulated parameter to decide what to do after that. So i will not need to use removeOdd function inside the case. ( maybe i will need to use in every guard definition if i choose to use guards ) Is this it? Is this the only difference between them ? And if it is, why haskell needed do implement both of them. Can't we use function like removeOdd before using it on case or guard functions ? Thanks, and sorry if my english is bad. Semih Masat -------------- next part -------------- An HTML attachment was scrubbed... URL: From masat.semih at gmail.com Thu Jul 7 01:16:56 2016 From: masat.semih at gmail.com (Semih Masat) Date: Thu, 7 Jul 2016 04:16:56 +0300 Subject: [Haskell-beginners] Case vs Guards. I still don't know what is the difference In-Reply-To: References: Message-ID: Sorry, if i am flooding. To make it clear what i wanted to say in last section on previous mail. Lets say i have a list of numbers and i want to do different things in case of different even numbers on that list. If i use guards i will do it like this : nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] howManyEvens = length(removeOdd(nums)) isItOk count | count > 10 = "Too much" | count > 8 = "Isn't this a little much?" | count > 5 = "I think this is ok" | count > 3 = "Little more please" | count > 0 = "Ooo, cmon" | otherwise = "We gonna die" result = isItOk howManyEvens This is a very stupid example but this will work i guess. And if i wanted to this with *case* , i will do it like; isItOk' nums = case (length(removeOdd(nums))) of 10 -> "Too much" 8 -> "Isn't this a little much?" 5 -> "I think this is ok" 3 -> "Little more please" 0 -> "Ooo, cmon" x -> "i don't even" So the only different thing is i didn't need to create *howManyEvens* constant. PS: While i writing this. I realized that with case, i need to use pattern matching but with guards i can use other functions if i wanted to. ( like count > 10 ) Sorry for asking prematurely. And if anyone reaches this email by google search. Look at this explanation : http://stackoverflow.com/a/4156831 To the authors : Please, if you writing a book a blog post about haskell. Don't create same function in different styles. We don't understand which one we need to use and why we have all different choices. Thanks. Semih On Thu, Jul 7, 2016 at 3:43 AM, Semih Masat wrote: > Hello, > > I am new to Haskell and trying to learn it with learnyouahaskell.com and > Pluralsight Haskell course. > > And i have a very noob question. > > I understand that *if .. else* is just a syntactic sugar over *case. *But > what about guards then ? > > Are guards also *case *in different syntax ? Or vice versa ? Like with an > example. > > > anyEven nums > | (length (removeOdd nums)) > 0 = True > | otherwise = False > > > anyEven' nums = case (removeOdd nums) of > [] -> False > (x:xs) -> True > > I can do the same thing with both of them. > > As i understand the only different thing is, with *case *i can manipulate > the parameter (like here in the example i used removeOdd) and can use the > manipulated parameter to decide what to do after that. > So i will not need to use removeOdd function inside the case. ( maybe i > will need to use in every guard definition if i choose to use guards ) > > Is this it? > > Is this the only difference between them ? > > And if it is, why haskell needed do implement both of them. Can't we use > function like removeOdd before using it on case or guard functions ? > > > Thanks, and sorry if my english is bad. > > Semih Masat > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tanuki at gmail.com Thu Jul 7 01:43:35 2016 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Wed, 6 Jul 2016 18:43:35 -0700 Subject: [Haskell-beginners] Case vs Guards. I still don't know what is the difference In-Reply-To: References: Message-ID: One important feature of guards is that passing a pattern but failing all the guards falls through to the next pattern. Toy example: maybeGT5 x | x > 5 = Just x maybeGT5 _ = Nothing On Jul 6, 2016 6:17 PM, "Semih Masat" wrote: > Sorry, if i am flooding. > > To make it clear what i wanted to say in last section on previous mail. > > > > Lets say i have a list of numbers and i want to do different things in > case of different even numbers on that list. > > If i use guards i will do it like this : > > nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] > howManyEvens = length(removeOdd(nums)) > > isItOk count > | count > 10 = "Too much" > | count > 8 = "Isn't this a little much?" > | count > 5 = "I think this is ok" > | count > 3 = "Little more please" > | count > 0 = "Ooo, cmon" > | otherwise = "We gonna die" > > result = isItOk howManyEvens > > This is a very stupid example but this will work i guess. > > And if i wanted to this with *case* , i will do it like; > > isItOk' nums = case (length(removeOdd(nums))) of > 10 -> "Too much" > 8 -> "Isn't this a little much?" > 5 -> "I think this is ok" > 3 -> "Little more please" > 0 -> "Ooo, cmon" > x -> "i don't even" > > So the only different thing is i didn't need to create *howManyEvens* > constant. > > > PS: While i writing this. I realized that with case, i need to use pattern > matching but with guards i can use other functions if i wanted to. ( like > count > 10 ) > Sorry for asking prematurely. And if anyone reaches this email by google > search. Look at this explanation : http://stackoverflow.com/a/4156831 > > To the authors : Please, if you writing a book a blog post about haskell. > Don't create same function in different styles. We don't understand which > one we need to use and why we have all different choices. > > Thanks. > Semih > > On Thu, Jul 7, 2016 at 3:43 AM, Semih Masat wrote: > >> Hello, >> >> I am new to Haskell and trying to learn it with learnyouahaskell.com and >> Pluralsight Haskell course. >> >> And i have a very noob question. >> >> I understand that *if .. else* is just a syntactic sugar over *case. *But >> what about guards then ? >> >> Are guards also *case *in different syntax ? Or vice versa ? Like with >> an example. >> >> >> anyEven nums >> | (length (removeOdd nums)) > 0 = True >> | otherwise = False >> >> >> anyEven' nums = case (removeOdd nums) of >> [] -> False >> (x:xs) -> True >> >> I can do the same thing with both of them. >> >> As i understand the only different thing is, with *case *i can >> manipulate the parameter (like here in the example i used removeOdd) and >> can use the manipulated parameter to decide what to do after that. >> So i will not need to use removeOdd function inside the case. ( maybe i >> will need to use in every guard definition if i choose to use guards ) >> >> Is this it? >> >> Is this the only difference between them ? >> >> And if it is, why haskell needed do implement both of them. Can't we use >> function like removeOdd before using it on case or guard functions ? >> >> >> Thanks, and sorry if my english is bad. >> >> Semih Masat >> > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tushar4r at gmail.com Thu Jul 7 02:12:43 2016 From: tushar4r at gmail.com (Tushar Tyagi) Date: Thu, 7 Jul 2016 07:42:43 +0530 Subject: [Haskell-beginners] Case vs Guards. I still don't know what is the difference In-Reply-To: References: Message-ID: It's great that you understood that the idiom of using case expressions is with pattern matching -- using it to count numbers is like using a crane to pick a packet of sugar -- pretty inefficient. The case expression/pattern matching is very powerful and expressive. And I will be using a single example for multiple definitions (which you advised against), hoping that you see the difference between different idioms. Take a look at the definition of map below: map' f xs = case xs of [] -> [] (y:ys) -> f y : map' f ys Without pattern matching you will be using library functions like `null`, `head`, or `tail` and one of the downsides of these is that they crash the program in case `head` and `tail` are used with empty list without null checking. With the null check, the program looks inelegant (and is not the standard idiom): map'' f xs = if null xs then [] else let hd = head xs tl = tail xs in (f hd) : (map'' f tl) You can clearly see the superior one. Of course, pattern matching is not used only with case expressions: here is the definition of drop with and without case: drop'' n xs = case (n, xs) of (0, xs) -> xs (_, []) -> [] (n, y:ys) -> drop'' (n-1) ys drop' 0 xs = xs drop' _ [] = [] drop' n (x:xs) = drop' (n-1) xs In my opinion, the second one without the case expression is clearer. One more use case of case expression (and pattern matching) is when you start creating your own datatypes. Then you can destructure the type and add the required logic based on the type: data MyType a b = TypeA a | TypeB b deriving (Show) which_type a = case a of TypeA a -> "Type A" -- Or some better logic here. TypeB b -> "Type B" Hope this makes things a bit clearer. On Thu, Jul 7, 2016 at 6:46 AM, Semih Masat wrote: > Sorry, if i am flooding. > > To make it clear what i wanted to say in last section on previous mail. > > > > Lets say i have a list of numbers and i want to do different things in > case of different even numbers on that list. > > If i use guards i will do it like this : > > nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] > howManyEvens = length(removeOdd(nums)) > > isItOk count > | count > 10 = "Too much" > | count > 8 = "Isn't this a little much?" > | count > 5 = "I think this is ok" > | count > 3 = "Little more please" > | count > 0 = "Ooo, cmon" > | otherwise = "We gonna die" > > result = isItOk howManyEvens > > This is a very stupid example but this will work i guess. > > And if i wanted to this with *case* , i will do it like; > > isItOk' nums = case (length(removeOdd(nums))) of > 10 -> "Too much" > 8 -> "Isn't this a little much?" > 5 -> "I think this is ok" > 3 -> "Little more please" > 0 -> "Ooo, cmon" > x -> "i don't even" > > So the only different thing is i didn't need to create *howManyEvens* > constant. > > > PS: While i writing this. I realized that with case, i need to use pattern > matching but with guards i can use other functions if i wanted to. ( like > count > 10 ) > Sorry for asking prematurely. And if anyone reaches this email by google > search. Look at this explanation : http://stackoverflow.com/a/4156831 > > To the authors : Please, if you writing a book a blog post about haskell. > Don't create same function in different styles. We don't understand which > one we need to use and why we have all different choices. > > Thanks. > Semih > > On Thu, Jul 7, 2016 at 3:43 AM, Semih Masat wrote: > >> Hello, >> >> I am new to Haskell and trying to learn it with learnyouahaskell.com and >> Pluralsight Haskell course. >> >> And i have a very noob question. >> >> I understand that *if .. else* is just a syntactic sugar over *case. *But >> what about guards then ? >> >> Are guards also *case *in different syntax ? Or vice versa ? Like with >> an example. >> >> >> anyEven nums >> | (length (removeOdd nums)) > 0 = True >> | otherwise = False >> >> >> anyEven' nums = case (removeOdd nums) of >> [] -> False >> (x:xs) -> True >> >> I can do the same thing with both of them. >> >> As i understand the only different thing is, with *case *i can >> manipulate the parameter (like here in the example i used removeOdd) and >> can use the manipulated parameter to decide what to do after that. >> So i will not need to use removeOdd function inside the case. ( maybe i >> will need to use in every guard definition if i choose to use guards ) >> >> Is this it? >> >> Is this the only difference between them ? >> >> And if it is, why haskell needed do implement both of them. Can't we use >> function like removeOdd before using it on case or guard functions ? >> >> >> Thanks, and sorry if my english is bad. >> >> Semih Masat >> > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fordforox at gmail.com Thu Jul 7 07:31:20 2016 From: fordforox at gmail.com (OxFord) Date: Thu, 7 Jul 2016 09:31:20 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. Message-ID: Hello, Why is there no default O(1) random access list data structure in haskell (for example clojure has [] vector). I would expect that this kind of data structure is used very often, so you shouldn't need to import one yourself. Is it safe to assume that ' reverse [1, 2, 3, 4, 5] ' is O(1) ? Is it safe to assume that main = x = [1, 2, 3, 4, 5] x = reverse reverse x won't use more space than for the initial [1, 2, 3, 4, 5] list? (No copy of x) Why is array indexeded by ! and list by !!. Shouldn't they be both instances of something like Indexable? King regards, Ford -------------- next part -------------- An HTML attachment was scrubbed... URL: From masat.semih at gmail.com Thu Jul 7 09:21:40 2016 From: masat.semih at gmail.com (Semih Masat) Date: Thu, 7 Jul 2016 12:21:40 +0300 Subject: [Haskell-beginners] Case vs Guards. I still don't know what is the difference In-Reply-To: References: Message-ID: Thank you Theodore and Tushar. Great examples and help. I am understanding better now. On Thu, Jul 7, 2016 at 5:12 AM, Tushar Tyagi wrote: > It's great that you understood that the idiom of using case expressions is > with pattern matching -- using it to count numbers is like using a crane to > pick a packet of sugar -- pretty inefficient. > > The case expression/pattern matching is very powerful and expressive. And > I will be using a single example for multiple definitions (which you > advised against), hoping that you see the difference between different > idioms. > > Take a look at the definition of map below: > > map' f xs = case xs of > [] -> [] > (y:ys) -> f y : map' f ys > > Without pattern matching you will be using library functions like `null`, > `head`, or `tail` and one of the downsides of these is that they crash the > program in case `head` and `tail` are used with empty list without null > checking. With the null check, the program looks inelegant (and is not the > standard idiom): > > map'' f xs = if null xs > then [] > else let hd = head xs > tl = tail xs in > (f hd) : (map'' f tl) > > You can clearly see the superior one. > > Of course, pattern matching is not used only with case expressions: here > is the definition of drop with and without case: > > drop'' n xs = case (n, xs) of > (0, xs) -> xs > (_, []) -> [] > (n, y:ys) -> drop'' (n-1) ys > > drop' 0 xs = xs > drop' _ [] = [] > drop' n (x:xs) = drop' (n-1) xs > > In my opinion, the second one without the case expression is clearer. > > One more use case of case expression (and pattern matching) is when you > start creating your own datatypes. Then you can destructure the type and > add the required logic based on the type: > > data MyType a b = TypeA a | TypeB b > deriving (Show) > > which_type a = case a of > TypeA a -> "Type A" -- Or some better logic here. > TypeB b -> "Type B" > > Hope this makes things a bit clearer. > > > On Thu, Jul 7, 2016 at 6:46 AM, Semih Masat wrote: > >> Sorry, if i am flooding. >> >> To make it clear what i wanted to say in last section on previous mail. >> >> >> >> Lets say i have a list of numbers and i want to do different things in >> case of different even numbers on that list. >> >> If i use guards i will do it like this : >> >> nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] >> howManyEvens = length(removeOdd(nums)) >> >> isItOk count >> | count > 10 = "Too much" >> | count > 8 = "Isn't this a little much?" >> | count > 5 = "I think this is ok" >> | count > 3 = "Little more please" >> | count > 0 = "Ooo, cmon" >> | otherwise = "We gonna die" >> >> result = isItOk howManyEvens >> >> This is a very stupid example but this will work i guess. >> >> And if i wanted to this with *case* , i will do it like; >> >> isItOk' nums = case (length(removeOdd(nums))) of >> 10 -> "Too much" >> 8 -> "Isn't this a little much?" >> 5 -> "I think this is ok" >> 3 -> "Little more please" >> 0 -> "Ooo, cmon" >> x -> "i don't even" >> >> So the only different thing is i didn't need to create *howManyEvens* >> constant. >> >> >> PS: While i writing this. I realized that with case, i need to use >> pattern matching but with guards i can use other functions if i wanted to. >> ( like count > 10 ) >> Sorry for asking prematurely. And if anyone reaches this email by google >> search. Look at this explanation : http://stackoverflow.com/a/4156831 >> >> To the authors : Please, if you writing a book a blog post about haskell. >> Don't create same function in different styles. We don't understand which >> one we need to use and why we have all different choices. >> >> Thanks. >> Semih >> >> On Thu, Jul 7, 2016 at 3:43 AM, Semih Masat >> wrote: >> >>> Hello, >>> >>> I am new to Haskell and trying to learn it with learnyouahaskell.com >>> and Pluralsight Haskell course. >>> >>> And i have a very noob question. >>> >>> I understand that *if .. else* is just a syntactic sugar over *case. *But >>> what about guards then ? >>> >>> Are guards also *case *in different syntax ? Or vice versa ? Like with >>> an example. >>> >>> >>> anyEven nums >>> | (length (removeOdd nums)) > 0 = True >>> | otherwise = False >>> >>> >>> anyEven' nums = case (removeOdd nums) of >>> [] -> False >>> (x:xs) -> True >>> >>> I can do the same thing with both of them. >>> >>> As i understand the only different thing is, with *case *i can >>> manipulate the parameter (like here in the example i used removeOdd) and >>> can use the manipulated parameter to decide what to do after that. >>> So i will not need to use removeOdd function inside the case. ( maybe i >>> will need to use in every guard definition if i choose to use guards ) >>> >>> Is this it? >>> >>> Is this the only difference between them ? >>> >>> And if it is, why haskell needed do implement both of them. Can't we use >>> function like removeOdd before using it on case or guard functions ? >>> >>> >>> Thanks, and sorry if my english is bad. >>> >>> Semih Masat >>> >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From timmelzer at gmail.com Thu Jul 7 09:40:10 2016 From: timmelzer at gmail.com (Norbert Melzer) Date: Thu, 07 Jul 2016 11:40:10 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. In-Reply-To: Message-ID: <87oa69dbwl.fsf@gmail.com> OxFord writes: > Hello, > > Why is there no default O(1) random access list data structure in haskell > (for example clojure has [] vector). I would expect that this kind of data > structure is used very often, so you shouldn't need to import one yourself. Whenever I try to reach for something with O(1) random access, then I have used imperative languages for too long ;) In most cases I am able to rewrite my algorithms to work by iterating instead of random access. And if I do not come up with such an algorithm, I then do realize most of the time, that I do want to have a Map or Set with a certain Key-Type, which is very unlikely to be Num. > Is it safe to assume that ' reverse [1, 2, 3, 4, 5] ' is O(1) ? It is not. Reversing in constant time is impossible without dooing nasty hacks, and make it necessary to not only save distinct elements, but its reading direction in addition. Also to make this actually happen you need something in the spirit of a C Array or a doubly linked list. Also you will get in trouble as soon as you want to change an element in the reversed collection, but not in the original one. As soon as you want distinct containers you need to copy, and copying is O(n) at least. > Is it safe to assume that main = > x = [1, 2, 3, 4, 5] > x = reverse reverse x > won't use more space than for the initial [1, 2, 3, 4, 5] list? (No copy of > x) According to my observations it is not safe to assume anything about memory in GC'd languages. > Why is array indexeded by ! and list by !!. Shouldn't they be both > instances of something like Indexable? Because indexed access is always something you should think about, and for lists you should think about it even twice. Thats just a guess though. From imantc at gmail.com Thu Jul 7 09:51:32 2016 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 7 Jul 2016 11:51:32 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. In-Reply-To: <87oa69dbwl.fsf@gmail.com> References: <87oa69dbwl.fsf@gmail.com> Message-ID: > indexed access is always something you should think about, yep, leave aside plenty of time for debugging when you use !! or "head" with list or ! with map package "safe" helps to safely access lists: https://hackage.haskell.org/package/safe​ -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcin.jan.mrotek at gmail.com Thu Jul 7 17:05:43 2016 From: marcin.jan.mrotek at gmail.com (Marcin Mrotek) Date: Thu, 7 Jul 2016 19:05:43 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. In-Reply-To: References: Message-ID: Hello, > Why is there no default O(1) random access list data structure in haskell > (for example clojure has [] vector). I would expect that this kind of data > structure is used very often, so you shouldn't need to import one yourself. Vector (https://hackage.haskell.org/package/vector) can be considered standard for all intents and purposes; it's one of the core libraries (https://wiki.haskell.org/Library_submissions#The_Libraries). Containers in Haskell are in general imported as libraries, it's no different than Map, Set, or Sequence, for example. I'm not sure if it's used all that often in Haskell - it's excellent for numeric code, or other cases when one just needs a big dumb block of data (though streaming with pipes or conduit might be a better solution in some cases), but for otherwise something like IntMap or Sequence might be more useful. >Why is array indexeded by ! and list by !!. Shouldn't they be both instances of something like Indexable? Indexing a list is O(n) and generally a bad idea. Proliferating type classes just to cover the rare use case of code that is indifferent to whether the indexing is done in O(n) or O(1) seems pointless to me. Best regards, Marcin Mrotek From fordforox at gmail.com Thu Jul 7 17:16:44 2016 From: fordforox at gmail.com (OxFord) Date: Thu, 7 Jul 2016 19:16:44 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. In-Reply-To: References: Message-ID: Thanks ! 2016-07-07 19:05 GMT+02:00 Marcin Mrotek : > Hello, > > > Why is there no default O(1) random access list data structure in haskell > > (for example clojure has [] vector). I would expect that this kind of > data > > structure is used very often, so you shouldn't need to import one > yourself. > > Vector (https://hackage.haskell.org/package/vector) can be considered > standard for all intents and purposes; it's one of the core libraries > (https://wiki.haskell.org/Library_submissions#The_Libraries). > Containers in Haskell are in general imported as libraries, it's no > different than Map, Set, or Sequence, for example. I'm not sure if > it's used all that often in Haskell - it's excellent for numeric code, > or other cases when one just needs a big dumb block of data (though > streaming with pipes or conduit might be a better solution in some > cases), but for otherwise something like IntMap or Sequence might be > more useful. > > >Why is array indexeded by ! and list by !!. Shouldn't they be both > instances of something like Indexable? > > Indexing a list is O(n) and generally a bad idea. Proliferating type > classes just to cover the rare use case of code that is indifferent to > whether the indexing is done in O(n) or O(1) seems pointless to me. > > Best regards, > Marcin Mrotek > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fordforox at gmail.com Thu Jul 7 17:30:44 2016 From: fordforox at gmail.com (OxFord) Date: Thu, 7 Jul 2016 19:30:44 +0200 Subject: [Haskell-beginners] search function by type Message-ID: Hello, is it possible to search for all functions that have concrete type? For example I want to convert [Char] to [Word], but I don't know whether function for that exist. Or I wanna find contructor for SomeSpecialType and I don't know it's name. Can you search those function in GHCI via some command? E.G. GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help [}{] :searchtype / :st [Char] -> [Word] Found X match(es): foo1 :: (Char -> Word) -> [Char] -> [Word] foo2 :: [Char] -> [Word] ... [}{] :st SomeSpecialType Found 1 match(es): foo3 :: ... -> .. -> SomeSpecialType King Regards, Ford -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.bernard at gmail.com Fri Jul 8 07:37:22 2016 From: andrew.bernard at gmail.com (Andrew Bernard) Date: Fri, 8 Jul 2016 17:37:22 +1000 Subject: [Haskell-beginners] search function by type In-Reply-To: References: Message-ID: Hi Ford, Take a look at Hoogle. Indispensable. https://www.haskell.org/hoogle/ Andrew From davidmringo at gmail.com Fri Jul 8 22:43:23 2016 From: davidmringo at gmail.com (David Ringo) Date: Fri, 08 Jul 2016 22:43:23 +0000 Subject: [Haskell-beginners] search function by type In-Reply-To: References: Message-ID: To add to what Andrew said, you can get Hoogle integration in GHCi with some custom commands: https://wiki.haskell.org/Hoogle#GHCi_Integration Hoogle is not perfect, but it's the closest you'll find to what you want. You could even define some augmenting functions to trim its (often large) output and bind them to GHCi commands as well. On Fri, Jul 8, 2016 at 1:37 AM Andrew Bernard wrote: > Hi Ford, > > Take a look at Hoogle. Indispensable. > > https://www.haskell.org/hoogle/ > > Andrew > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin.drautzburg at web.de Sat Jul 9 10:01:12 2016 From: martin.drautzburg at web.de (martin) Date: Sat, 9 Jul 2016 12:01:12 +0200 Subject: [Haskell-beginners] How to move nodes in Data.Tree.Zipper Message-ID: <5780CB68.30605@web.de> Hello all, I've been playing with Data.Tree.Zipper and one of the tasks I set for myself was to move a node to another position. I endet up in a situation, where I no longer have a clear understanding what "moving" means. Data.Tree.Zipper distinguishes between Nodes ("Full") and Space ("Empty"). So I thought to move a nde I need to know the node to be moved ("Full") and the space where it shall be moved to ("Empty") But I need to do two things: (1) remove the node from its original position (2) insert the node at the empty space given. Both operations are supported by D.T.Z, but once I removed the node, I have a new Zipper, while the space given still refers to the original zipper. The new Zipper has no idea where the deleted node shall be inserted and the original empty space doesn't have the node removed. This is not the fault of D.T.Z, but in a way a real-world problem I had been unaware of. With my original idea I could have moved a node to a subspace of itself, which makes no real sense. It appears that giving two zippers to a tree-modifying function is utterly useless when they refer to the same tree and both undergo modifications by the function. What would be a correct way to think about this? From fordforox at gmail.com Sat Jul 9 12:54:40 2016 From: fordforox at gmail.com (Ford) Date: Sat, 09 Jul 2016 14:54:40 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. In-Reply-To: <87oa69dbwl.fsf@gmail.com> References: <87oa69dbwl.fsf@gmail.com> Message-ID: <410c9db5-6c37-4dbd-8ef3-4922c4501566@typeapp.com> I am trying to implement ant colony optimization algorithm (or any other similar simulation) . In procedural language I would keep the world map in 2D matrix that provides O(1) collision check and O(1) ant position change. Should I try to implement this in haskell in the same way (2d mutable matrix)? If yes,  what data structure should I use? If not,  how can I achieve the same performance as in procedural style? (The memory usage is also important.) Thank you for any tips. King regards, Ford Odesláno z BlueMail 7. 7. 2016 11:40 AM, 11:40 AM, Norbert Melzer napsal/a: > >OxFord writes: > >> Hello, >> >> Why is there no default O(1) random access list data structure in >haskell >> (for example clojure has [] vector). I would expect that this kind of >data >> structure is used very often, so you shouldn't need to import one >yourself. > >Whenever I try to reach for something with O(1) random access, then I >have used imperative languages for too long ;) In most cases I am able >to rewrite my algorithms to work by iterating instead of random access. >And if I do not come up with such an algorithm, I then do realize most >of the time, that I do want to have a Map or Set with a certain >Key-Type, which is very unlikely to be Num. > >> Is it safe to assume that ' reverse [1, 2, 3, 4, 5] ' is O(1) ? > >It is not. Reversing in constant time is impossible without dooing >nasty >hacks, and make it necessary to not only save distinct elements, but >its >reading direction in addition. > >Also to make this actually happen you need something in the spirit of >a C Array or a doubly linked list. > >Also you will get in trouble as soon as you want to change an element >in >the reversed collection, but not in the original one. > >As soon as you want distinct containers you need to copy, and copying >is >O(n) at least. > >> Is it safe to assume that main = >> x = [1, 2, 3, 4, 5] >> x = reverse reverse x >> won't use more space than for the initial [1, 2, 3, 4, 5] list? (No >copy of >> x) > >According to my observations it is not safe to assume anything about >memory in GC'd languages. > >> Why is array indexeded by ! and list by !!. Shouldn't they be both >> instances of something like Indexable? > >Because indexed access is always something you should think about, and >for lists you should think about it even twice. Thats just a guess >though. >_______________________________________________ >Beginners mailing list >Beginners at haskell.org >http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -------------- next part -------------- An HTML attachment was scrubbed... URL: From timmelzer at gmail.com Sat Jul 9 22:22:54 2016 From: timmelzer at gmail.com (Norbert Melzer) Date: Sun, 10 Jul 2016 00:22:54 +0200 Subject: [Haskell-beginners] Haskell laziness and data structures. In-Reply-To: <410c9db5-6c37-4dbd-8ef3-4922c4501566@typeapp.com> Message-ID: <87oa66ladd.fsf@gmail.com> Ford writes: > I am trying to implement ant colony optimization algorithm (or any > other similar simulation) . In procedural language I would keep the > world map in 2D matrix that provides O(1) collision check and O(1) ant > position change. I do not know that particular algorithm, but most algorithms are even written down imperatively. First check if odd, iff so do foo and then repeat first step with next item else repeat step 1 with next item without doing foo. In FP the world is working in a slightly different way. FP would say the above roughly like “for all odd items in a list do foo” Maybe the difference is not that obvious right now. But trying to repostulate the wording of an algorithm from imperative style to declarative style, does help a lot very often. As I already said, when I think to need mutable datastructures, most of the time my algorithm is not declarative enough. Try to reach for a different algorithm which has the same goal, or at least try to rethink the one you currently have. > (The memory usage is also important.) It is always, but it is also very hard to reason about memory usage in GC'd languages. You might be able to reason about pure allocations while assuming that garbage is collected instantly, but this is just not true. Sometimes even immutable stuff is changed in place, just because the runtime knows that the old value will never be used again. And this does massively depends on the optimisation, the compiler and the runtime used. > Thank you for any tips. > > King regards, > > Ford > > Odesláno z BlueMail > > > > 7. 7. 2016 11:40 AM, 11:40 AM, Norbert Melzer napsal/a: >> >>OxFord writes: >> >>> Hello, >>> >>> Why is there no default O(1) random access list data structure in >>haskell >>> (for example clojure has [] vector). I would expect that this kind of >>data >>> structure is used very often, so you shouldn't need to import one >>yourself. >> >>Whenever I try to reach for something with O(1) random access, then I >>have used imperative languages for too long ;) In most cases I am able >>to rewrite my algorithms to work by iterating instead of random access. >>And if I do not come up with such an algorithm, I then do realize most >>of the time, that I do want to have a Map or Set with a certain >>Key-Type, which is very unlikely to be Num. >> >>> Is it safe to assume that ' reverse [1, 2, 3, 4, 5] ' is O(1) ? >> >>It is not. Reversing in constant time is impossible without dooing >>nasty >>hacks, and make it necessary to not only save distinct elements, but >>its >>reading direction in addition. >> >>Also to make this actually happen you need something in the spirit of >>a C Array or a doubly linked list. >> >>Also you will get in trouble as soon as you want to change an element >>in >>the reversed collection, but not in the original one. >> >>As soon as you want distinct containers you need to copy, and copying >>is >>O(n) at least. >> >>> Is it safe to assume that main = >>> x = [1, 2, 3, 4, 5] >>> x = reverse reverse x >>> won't use more space than for the initial [1, 2, 3, 4, 5] list? (No >>copy of >>> x) >> >>According to my observations it is not safe to assume anything about >>memory in GC'd languages. >> >>> Why is array indexeded by ! and list by !!. Shouldn't they be both >>> instances of something like Indexable? >> >>Because indexed access is always something you should think about, and >>for lists you should think about it even twice. Thats just a guess >>though. >>_______________________________________________ >>Beginners mailing list >>Beginners at haskell.org >>http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From fordforox at gmail.com Mon Jul 11 19:24:24 2016 From: fordforox at gmail.com (Ford) Date: Mon, 11 Jul 2016 21:24:24 +0200 Subject: [Haskell-beginners] Polymorphism Message-ID: Hello, Why exporting a function doesn't force you to make its inputs derive a typeclass? That would solve all name clashing (just derive also or give different name,  because it is obviously too generic). Why can't you overload field accessor via typeclass easily? data Foo = Foo {HasSize => size :: Int} > :t size HasSize a => size a -> Int Why is String not deprecated yet,  throwing warning into your face. I think that haskell is really missing some uniformity, there is nothing like AbstractString and AbstractArray (something like java Collections) so a lot of modules introduces its own functions that are just aliases for others.  (Even Prelude itself suffers from this - map fmap liftM, pure return...). King regards! Odesláno z BlueMail -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin.drautzburg at web.de Sat Jul 16 09:28:30 2016 From: martin.drautzburg at web.de (martin) Date: Sat, 16 Jul 2016 11:28:30 +0200 Subject: [Haskell-beginners] Values vs. Continuations Message-ID: <5789FE3E.7030907@web.de> Hello all, a suspended computation in the Continuation Monad is something you can apply a functio to, right? But this holds for ordinary values as well. In fact, some point out that continuations (acutually suspended computations) are almost indistinguishable from values. If that's the case, can somebody please explain what exactly is gained when we turn everything inside-out to get from values to suspended computations? From dominikbollmann at gmail.com Sat Jul 16 22:40:42 2016 From: dominikbollmann at gmail.com (Dominik Bollmann) Date: Sun, 17 Jul 2016 00:40:42 +0200 Subject: [Haskell-beginners] What's an idiomatic Haskell solution to solve the "Maximum Subarray Problem"? Message-ID: <87vb05qk9h.fsf@t450s.i-did-not-set--mail-host-address--so-tickle-me> Hi all, I've recently been trying to implement the "maximum subarray problem" from [1] in Haskell. My first, naive solution looked like this: maxSubArray :: [Int] -> [Int] maxSubArray [] = [] maxSubArray [x] = [x] maxSubArray xs@(_:_:_) = maxArr (maxArr maxHd maxTl) (maxCrossingArray hd tl) where (hd,tl) = splitAt (length xs `div` 2) xs maxHd = maxSubArray hd maxTl = maxSubArray tl maxCrossingArray :: [Int] -> [Int] -> [Int] maxCrossingArray hd tl | null hd || null tl = error "maxArrayBetween: hd/tl empty!" maxCrossingArray hd tl = maxHd ++ maxTl where maxHd = reverse . foldr1 maxArr . tail $ inits (reverse hd) -- we need to go from the center leftwards, which is why we -- reverse the list `hd'. maxTl = foldr1 maxArr . tail $ inits tl maxArr :: [Int] -> [Int] -> [Int] maxArr xs ys | sum xs > sum ys = xs | otherwise = ys While I originally thought that this should run in O(n*log n), a closer examination revealed that the (++) as well as maxHd and maxTl computations inside function `maxCrossingArray` are O(n^2), which makes solving one of the provided test cases in [1] infeasible. Hence, I rewrote the above code using Data.Array into the following: data ArraySum = ArraySum { from :: Int , to :: Int , value :: Int } deriving (Eq, Show) instance Ord ArraySum where ArraySum _ _ v1 <= ArraySum _ _ v2 = v1 <= v2 maxSubList :: [Int] -> [Int] maxSubList xs = take (to-from+1) . drop (from-1) $ xs where arr = array (1, length xs) [(i,v) | (i,v) <- zip [1..] xs] ArraySum from to val = findMaxArr (1, length xs) arr findMaxArr :: (Int, Int) -> Array Int Int -> ArraySum findMaxArr (start, end) arr | start > end = error "findMaxArr: start > end" | start == end = ArraySum start end (arr ! start) | otherwise = max (max hd tl) (ArraySum leftIdx rightIdx (leftVal+rightVal)) where mid = (start + end) `div` 2 hd = findMaxArr (start, mid) arr tl = findMaxArr (mid+1, end) arr (leftIdx, leftVal) = snd $ findMax mid [mid-1,mid-2..start] (rightIdx, rightVal) = snd $ findMax (mid+1) [mid+2,mid+3..end] findMax pos = foldl' go ((pos, arr ! pos), (pos, arr ! pos)) go ((currIdx, currSum), (maxIdx, maxSum)) idx | newSum >= maxSum = ((idx, newSum), (idx, newSum)) | otherwise = ((idx, newSum), (maxIdx, maxSum)) where newSum = currSum + (arr ! idx) I believe this runs in O(n*log n) now and is fast enough for the purpose of solving the Hackerrank challenge [1]. However, I feel this second solution is not very idiomatic Haskell code and I would prefer the clarity of the first solution over the second, if somehow I could make it more efficient. Therefore my question: What would be an efficient, yet idiomatic solution to solving the "maximum subarray problem" in Haskell? (Note: I'm aware that this problem can be solved in O(n), but I'm also happy with idiomatic Haskell solutions running in O(n*log n)) Thanks, Dominik. [1] https://www.hackerrank.com/challenges/maxsubarray From tanuki at gmail.com Sun Jul 17 05:14:23 2016 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Sat, 16 Jul 2016 22:14:23 -0700 Subject: [Haskell-beginners] What's an idiomatic Haskell solution to solve the "Maximum Subarray Problem"? In-Reply-To: <87vb05qk9h.fsf@t450s.i-did-not-set--mail-host-address--so-tickle-me> References: <87vb05qk9h.fsf@t450s.i-did-not-set--mail-host-address--so-tickle-me> Message-ID: -- Not beautifully idiomatic, but not too bad, and O(n): data SolutionState = SSInitial | SS Int Int Int solve :: [Int] -> SolutionState solve = foldr go SSInitial where go x (SS dense best sparse) = let dense' = max x (dense + x) best' = max best dense' sparse' = max (sparse + x) (max sparse x) in SS dense' best' sparse' go x SSInitial = SS x x x On Sat, Jul 16, 2016 at 3:40 PM, Dominik Bollmann wrote: > > Hi all, > > I've recently been trying to implement the "maximum subarray problem" > from [1] in Haskell. My first, naive solution looked like this: > > maxSubArray :: [Int] -> [Int] > maxSubArray [] = [] > maxSubArray [x] = [x] > maxSubArray xs@(_:_:_) = maxArr (maxArr maxHd maxTl) (maxCrossingArray hd > tl) > where > (hd,tl) = splitAt (length xs `div` 2) xs > maxHd = maxSubArray hd > maxTl = maxSubArray tl > > maxCrossingArray :: [Int] -> [Int] -> [Int] > maxCrossingArray hd tl > | null hd || null tl = error "maxArrayBetween: hd/tl empty!" > maxCrossingArray hd tl = maxHd ++ maxTl > where > maxHd = reverse . foldr1 maxArr . tail $ inits (reverse hd) > -- we need to go from the center leftwards, which is why we > -- reverse the list `hd'. > maxTl = foldr1 maxArr . tail $ inits tl > > maxArr :: [Int] -> [Int] -> [Int] > maxArr xs ys > | sum xs > sum ys = xs > | otherwise = ys > > While I originally thought that this should run in O(n*log n), a closer > examination revealed that the (++) as well as maxHd and maxTl > computations inside function `maxCrossingArray` are O(n^2), which makes > solving one of the provided test cases in [1] infeasible. > > Hence, I rewrote the above code using Data.Array into the following: > > data ArraySum = ArraySum { > from :: Int > , to :: Int > , value :: Int > } deriving (Eq, Show) > > instance Ord ArraySum where > ArraySum _ _ v1 <= ArraySum _ _ v2 = v1 <= v2 > > maxSubList :: [Int] -> [Int] > maxSubList xs = take (to-from+1) . drop (from-1) $ xs > where > arr = array (1, length xs) [(i,v) | (i,v) <- zip [1..] xs] > ArraySum from to val = findMaxArr (1, length xs) arr > > findMaxArr :: (Int, Int) -> Array Int Int -> ArraySum > findMaxArr (start, end) arr > | start > end = error "findMaxArr: start > end" > | start == end = ArraySum start end (arr ! start) > | otherwise = max (max hd tl) (ArraySum leftIdx rightIdx > (leftVal+rightVal)) > where > mid = (start + end) `div` 2 > hd = findMaxArr (start, mid) arr > tl = findMaxArr (mid+1, end) arr > (leftIdx, leftVal) = snd $ findMax mid [mid-1,mid-2..start] > (rightIdx, rightVal) = snd $ findMax (mid+1) [mid+2,mid+3..end] > findMax pos = foldl' go ((pos, arr ! pos), (pos, arr ! pos)) > go ((currIdx, currSum), (maxIdx, maxSum)) idx > | newSum >= maxSum = ((idx, newSum), (idx, newSum)) > | otherwise = ((idx, newSum), (maxIdx, maxSum)) > where newSum = currSum + (arr ! idx) > > I believe this runs in O(n*log n) now and is fast enough for the purpose > of solving the Hackerrank challenge [1]. > > However, I feel this second solution is not very idiomatic Haskell code > and I would prefer the clarity of the first solution over the second, if > somehow I could make it more efficient. > > Therefore my question: What would be an efficient, yet idiomatic > solution to solving the "maximum subarray problem" in Haskell? (Note: > I'm aware that this problem can be solved in O(n), but I'm also happy with > idiomatic Haskell solutions running in O(n*log n)) > > Thanks, Dominik. > > [1] https://www.hackerrank.com/challenges/maxsubarray > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tanuki at gmail.com Sun Jul 17 05:23:52 2016 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Sat, 16 Jul 2016 22:23:52 -0700 Subject: [Haskell-beginners] What's an idiomatic Haskell solution to solve the "Maximum Subarray Problem"? In-Reply-To: References: <87vb05qk9h.fsf@t450s.i-did-not-set--mail-host-address--so-tickle-me> Message-ID: Hmm, I clipped out all the boilerplate for interacting with HackerRank's expected I/O formats, but probably should have left this in for clarity: prettySS :: SolutionState -> String prettySS SSInitial = "Whoops! Didn't I filter nulls?" prettySS (SS _ dense sparse) = unwords $ map show [dense, sparse] On Sat, Jul 16, 2016 at 10:14 PM, Theodore Lief Gannon wrote: > -- Not beautifully idiomatic, but not too bad, and O(n): > > data SolutionState = SSInitial | SS Int Int Int > > solve :: [Int] -> SolutionState > solve = foldr go SSInitial where > go x (SS dense best sparse) = > let dense' = max x (dense + x) > best' = max best dense' > sparse' = max (sparse + x) (max sparse x) > in SS dense' best' sparse' > go x SSInitial = SS x x x > > > On Sat, Jul 16, 2016 at 3:40 PM, Dominik Bollmann < > dominikbollmann at gmail.com> wrote: > >> >> Hi all, >> >> I've recently been trying to implement the "maximum subarray problem" >> from [1] in Haskell. My first, naive solution looked like this: >> >> maxSubArray :: [Int] -> [Int] >> maxSubArray [] = [] >> maxSubArray [x] = [x] >> maxSubArray xs@(_:_:_) = maxArr (maxArr maxHd maxTl) (maxCrossingArray >> hd tl) >> where >> (hd,tl) = splitAt (length xs `div` 2) xs >> maxHd = maxSubArray hd >> maxTl = maxSubArray tl >> >> maxCrossingArray :: [Int] -> [Int] -> [Int] >> maxCrossingArray hd tl >> | null hd || null tl = error "maxArrayBetween: hd/tl empty!" >> maxCrossingArray hd tl = maxHd ++ maxTl >> where >> maxHd = reverse . foldr1 maxArr . tail $ inits (reverse hd) >> -- we need to go from the center leftwards, which is why we >> -- reverse the list `hd'. >> maxTl = foldr1 maxArr . tail $ inits tl >> >> maxArr :: [Int] -> [Int] -> [Int] >> maxArr xs ys >> | sum xs > sum ys = xs >> | otherwise = ys >> >> While I originally thought that this should run in O(n*log n), a closer >> examination revealed that the (++) as well as maxHd and maxTl >> computations inside function `maxCrossingArray` are O(n^2), which makes >> solving one of the provided test cases in [1] infeasible. >> >> Hence, I rewrote the above code using Data.Array into the following: >> >> data ArraySum = ArraySum { >> from :: Int >> , to :: Int >> , value :: Int >> } deriving (Eq, Show) >> >> instance Ord ArraySum where >> ArraySum _ _ v1 <= ArraySum _ _ v2 = v1 <= v2 >> >> maxSubList :: [Int] -> [Int] >> maxSubList xs = take (to-from+1) . drop (from-1) $ xs >> where >> arr = array (1, length xs) [(i,v) | (i,v) <- zip [1..] xs] >> ArraySum from to val = findMaxArr (1, length xs) arr >> >> findMaxArr :: (Int, Int) -> Array Int Int -> ArraySum >> findMaxArr (start, end) arr >> | start > end = error "findMaxArr: start > end" >> | start == end = ArraySum start end (arr ! start) >> | otherwise = max (max hd tl) (ArraySum leftIdx rightIdx >> (leftVal+rightVal)) >> where >> mid = (start + end) `div` 2 >> hd = findMaxArr (start, mid) arr >> tl = findMaxArr (mid+1, end) arr >> (leftIdx, leftVal) = snd $ findMax mid [mid-1,mid-2..start] >> (rightIdx, rightVal) = snd $ findMax (mid+1) [mid+2,mid+3..end] >> findMax pos = foldl' go ((pos, arr ! pos), (pos, arr ! pos)) >> go ((currIdx, currSum), (maxIdx, maxSum)) idx >> | newSum >= maxSum = ((idx, newSum), (idx, newSum)) >> | otherwise = ((idx, newSum), (maxIdx, maxSum)) >> where newSum = currSum + (arr ! idx) >> >> I believe this runs in O(n*log n) now and is fast enough for the purpose >> of solving the Hackerrank challenge [1]. >> >> However, I feel this second solution is not very idiomatic Haskell code >> and I would prefer the clarity of the first solution over the second, if >> somehow I could make it more efficient. >> >> Therefore my question: What would be an efficient, yet idiomatic >> solution to solving the "maximum subarray problem" in Haskell? (Note: >> I'm aware that this problem can be solved in O(n), but I'm also happy with >> idiomatic Haskell solutions running in O(n*log n)) >> >> Thanks, Dominik. >> >> [1] https://www.hackerrank.com/challenges/maxsubarray >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From list at mroth.net Sun Jul 24 17:17:08 2016 From: list at mroth.net (Michael Roth) Date: Sun, 24 Jul 2016 19:17:08 +0200 Subject: [Haskell-beginners] Learning Monads with 'setjmp' and 'longjmp' like actions Message-ID: <5794F814.5010904@mroth.net> Hi, I'm really trying hard to understand monads but I guess my brain is trapped in the imperative world. Below what I have done so far. But now I would like to implement something like this: do foo (label, jumped) <- setjmp bar longjmp label But I'm stuck. How can I implement 'setjmp' and 'longjmp' with my monad? I'm not able to grasp how can I design 'setjmp' and somehow create a label to use in 'longjmp'. Maybe my monad structure is not appropriate? Code follows: --------------------------------------------------------------- data World = SomeWorld deriving (Eq, Show) data ProgramResult a = Result { world :: World, result :: a } | Continue { world :: World, continue :: Program a } | Stopped { world :: World } newtype Program a = Program { runProgram :: World -> ProgramResult a } runComplete :: Program a -> World -> (World, a) runComplete prg world0 = case runProgram prg world0 of (Result world1 x1) -> (world1, x1) (Continue world1 prg1) -> runComplete prg1 world1 nop :: Program () nop = return () yield :: Program () yield = Program $ \world -> Continue world nop stop :: Program () stop = Program $ \world -> Stopped world instance Functor Program where fmap = liftM instance Applicative Program where pure = return (<*>) = ap instance Monad Program where return x = Program $ \world0 -> Result world0 x ma >>= fb = Program $ \world0 -> case runProgram ma world0 of (Result world1 x1) -> runProgram (fb x1) world1 (Continue world1 prg1) -> Continue world1 (prg1 >>= fb) (Stopped world1) -> Stopped world1 From dennis.raddle at gmail.com Thu Jul 28 22:09:54 2016 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Thu, 28 Jul 2016 15:09:54 -0700 Subject: [Haskell-beginners] reading lines with history from bash terminal in OS X Message-ID: I wrote a program first in Windows, where it works as expected, and now I'm using it in OS X and getting undesired behavior. It reads lines from the terminal using the getLine function. In Windows (DOS, actually) the up and down arrows can be used to choose previously entered lines. However, this does not work in bash in OS X. What do I need to get the history available via the arrow keys? D -------------- next part -------------- An HTML attachment was scrubbed... URL: From toad3k at gmail.com Fri Jul 29 00:05:33 2016 From: toad3k at gmail.com (David McBride) Date: Thu, 28 Jul 2016 20:05:33 -0400 Subject: [Haskell-beginners] reading lines with history from bash terminal in OS X In-Reply-To: References: Message-ID: You will have to use the haskeline library. FYI that is the library that makes ghci work. On Thu, Jul 28, 2016 at 6:09 PM, Dennis Raddle wrote: > I wrote a program first in Windows, where it works as expected, and now > I'm using it in OS X and getting undesired behavior. > > It reads lines from the terminal using the getLine function. In Windows > (DOS, actually) the up and down arrows can be used to choose previously > entered lines. However, this does not work in bash in OS X. > > What do I need to get the history available via the arrow keys? > > D > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dennis.raddle at gmail.com Fri Jul 29 00:35:27 2016 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Thu, 28 Jul 2016 17:35:27 -0700 Subject: [Haskell-beginners] reading lines with history from bash terminal in OS X In-Reply-To: References: Message-ID: Thanks. I'll install haskeline On Thu, Jul 28, 2016 at 5:05 PM, David McBride wrote: > You will have to use the haskeline library. FYI that is the library that > makes ghci work. > > On Thu, Jul 28, 2016 at 6:09 PM, Dennis Raddle > wrote: > >> I wrote a program first in Windows, where it works as expected, and now >> I'm using it in OS X and getting undesired behavior. >> >> It reads lines from the terminal using the getLine function. In Windows >> (DOS, actually) the up and down arrows can be used to choose previously >> entered lines. However, this does not work in bash in OS X. >> >> What do I need to get the history available via the arrow keys? >> >> D >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vmk8993 at gmail.com Sat Jul 30 07:25:11 2016 From: vmk8993 at gmail.com (Manikanda Krishnan) Date: Sat, 30 Jul 2016 12:55:11 +0530 Subject: [Haskell-beginners] time complexity of pattern matching Message-ID: I am new to haskell and I have found it extremely interesting and somewhat addictive .I am curious to know about the time complexity of a pattern matching expression . Thanks in advance . :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From rahulmutt at gmail.com Sat Jul 30 07:39:06 2016 From: rahulmutt at gmail.com (Rahul Muttineni) Date: Sat, 30 Jul 2016 13:09:06 +0530 Subject: [Haskell-beginners] time complexity of pattern matching In-Reply-To: References: Message-ID: Hi Manikanda, GHC does compilation by transformation and hence goes through a series of intermediate languages (like Core and STG) which are better suited for optimizations. Pattern matches are transformed into a sequence of case expressions. To answer you question, O(1) for simple patterns, but it really depends on the complexity of the pattern-matching expression and the Core-to-Core transformations that GHC applies. To truly understand the complexity, you need take a look at the Core/STG dump (I prefer STG since it's simple). If you have any particular code samples you'd like me to help you analyze, I'd be happy to do so. A basic example: --- data Color = Red | Blue | Green isRed Red = True isRed _ = False --- GHC will transform this to --- isRed x = case x of { Red -> True; DEFAULT -> False } --- You can think of a case as a switch expression in your standard imperative languages. A case expression will evaluate the thunk 'x' and perform a switch on the tag of the result. Each data constructor has an integer tag associated with it which will be the target of the switch. So the time complexity of `isRed` will be the time complexity of thunk evaluation which is impossible to predict because a thunk can be incredibly complex. Lazy evaluation is not so easy to analyze. It is highly context-sensitive. Hope that helps! Rahul Muttineni On Sat, Jul 30, 2016 at 12:55 PM, Manikanda Krishnan wrote: > I am new to haskell and I have found it extremely interesting and > somewhat addictive .I am curious to know about the time complexity of a > pattern matching expression . > > Thanks in advance . :) > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vmk8993 at gmail.com Sat Jul 30 08:19:16 2016 From: vmk8993 at gmail.com (Manikanda Krishnan) Date: Sat, 30 Jul 2016 13:49:16 +0530 Subject: [Haskell-beginners] time complexity of pattern matching In-Reply-To: References: Message-ID: Thanks Rahul , I am currently only using simple patterns trying to replicate the behavior of standard functions that I have learned so far in order to familiarize myself with the recursive way of doing things . Currently I am just using the GHCI directive (:set +s) to compare runtimes etc and computing algorithmic complexity like how I normally do it in imperative languages (not sure if they hold up in lazy settings), Can you point me to resources where I can learn how the a)GHC actually works . b)optimize or analyze the code I write in haskell . Thanks in advance :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From rahulmutt at gmail.com Sat Jul 30 08:39:44 2016 From: rahulmutt at gmail.com (Rahul Muttineni) Date: Sat, 30 Jul 2016 14:09:44 +0530 Subject: [Haskell-beginners] time complexity of pattern matching In-Reply-To: References: Message-ID: The way you're measuring algorithmic complexity does carry over to the lazy setting provided it's single-threaded because the order of execution is purely determined by the STG Code. In the concurrent lazy setting, it's a bit trickier since lightweight locking mechanisms occur when multiple threads evaluate the same thunk, making it non-deterministic. But the same problem is there for imperative concurrent programs. The best resources I've found on GHC are: Example-driven introduction to Core: https://davidterei.com/talks/2016-03-cs240h/ghc-compiler-slides.html GHC Illustrated (visual of the runtime system): https://takenobu-hs.github.io/downloads/haskell_ghc_illustrated.pdf Commentary: https://ghc.haskell.org/trac/ghc/wiki/Commentary *The Commentary is a bit out of date in some sections and very sparse, but that's the closest you can get on documented implementation details other than the Notes inside of the GHC source code itself. Beyond that, the GHC code base is your friend ;) But seriously though, a book on Haskell performance is long overdue. On Sat, Jul 30, 2016 at 1:49 PM, Manikanda Krishnan wrote: > Thanks Rahul , > > I am currently only using simple patterns trying to replicate the > behavior of standard functions that I have learned so far in order to > familiarize myself with the recursive way of doing things . > > Currently I am just using the GHCI directive (:set +s) to compare runtimes > etc and computing algorithmic complexity like how I normally do it in > imperative languages (not sure if they hold up in lazy settings), > > Can you point me to resources where I can learn how the > a)GHC actually works . > b)optimize or analyze the code I write in haskell . > > > Thanks in advance :) > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Rahul Muttineni -------------- next part -------------- An HTML attachment was scrubbed... URL: From vmk8993 at gmail.com Sat Jul 30 08:52:43 2016 From: vmk8993 at gmail.com (Manikanda Krishnan) Date: Sat, 30 Jul 2016 14:22:43 +0530 Subject: [Haskell-beginners] time complexity of pattern matching In-Reply-To: References: Message-ID: Thanks . On Sat, Jul 30, 2016 at 2:09 PM, Rahul Muttineni wrote: > The way you're measuring algorithmic complexity does carry over to the > lazy setting provided it's single-threaded because the order of execution > is purely determined by the STG Code. In the concurrent lazy setting, it's > a bit trickier since lightweight locking mechanisms occur when multiple > threads evaluate the same thunk, making it non-deterministic. But the same > problem is there for imperative concurrent programs. > > The best resources I've found on GHC are: > > Example-driven introduction to Core: > https://davidterei.com/talks/2016-03-cs240h/ghc-compiler-slides.html > GHC Illustrated (visual of the runtime system): > https://takenobu-hs.github.io/downloads/haskell_ghc_illustrated.pdf > Commentary: https://ghc.haskell.org/trac/ghc/wiki/Commentary > *The Commentary is a bit out of date in some sections and very sparse, but > that's the closest you can get on documented implementation details other > than the Notes inside of the GHC source code itself. > > Beyond that, the GHC code base is your friend ;) But seriously though, a > book on Haskell performance is long overdue. > > On Sat, Jul 30, 2016 at 1:49 PM, Manikanda Krishnan > wrote: > >> Thanks Rahul , >> >> I am currently only using simple patterns trying to replicate the >> behavior of standard functions that I have learned so far in order to >> familiarize myself with the recursive way of doing things . >> >> Currently I am just using the GHCI directive (:set +s) to compare >> runtimes etc and computing algorithmic complexity like how I normally do it >> in imperative languages (not sure if they hold up in lazy settings), >> >> Can you point me to resources where I can learn how the >> a)GHC actually works . >> b)optimize or analyze the code I write in haskell . >> >> >> Thanks in advance :) >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > > > -- > Rahul Muttineni > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Regards , *Manikanda Krishnan V* -------------- next part -------------- An HTML attachment was scrubbed... URL: From casual.dodo at gmail.com Sun Jul 31 18:44:14 2016 From: casual.dodo at gmail.com (Ramnath R Iyer) Date: Sun, 31 Jul 2016 18:44:14 +0000 Subject: [Haskell-beginners] Maybe Return? Message-ID: Hi all, I'm trying to write a fairly simple program to understand Haskell in practice. I am implementing a simple REPL where I can write some text, and that text can be parsed into a command with arguments. Then, I would like to be able to turn this into a 'plugin' system of sorts, with a module/logic per command. I understand the Text.Parsec library may already provide these things out of the box, but for now, I would prefer to reinvent the wheel. The program below is what I have working right now (very trivial). I want to modify this program, so that the `evaluate input` returns not a String, but a type X that includes information on whether to "continue" and show a prompt after rendering the result, or exit altogether. So the specific questions I have here are: 1. What would be a sensible type signature for X? 2. Assuming X to exist, what is the right way to modify main to use it? My current intuition is to modify the outputStrLn ... loop statements to include an if-then-else, but I'm not sure what the right modification is (all my attempts seemed like imperative programming and failed compilation unsurprisingly). import Evaluator import System.Console.Haskeline main :: IO () main = runInputT defaultSettings loop where loop :: InputT IO () loop = do line <- getInputLine ">> " case line of Nothing -> return () Just "quit" -> return () Just input -> do outputStrLn $ "Executing: " ++ (evaluate input) loop module Evaluator where evaluate :: String -> String evaluate value = value -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Sun Jul 31 18:55:56 2016 From: fa-ml at ariis.it (Francesco Ariis) Date: Sun, 31 Jul 2016 20:55:56 +0200 Subject: [Haskell-beginners] Maybe Return? In-Reply-To: References: Message-ID: <20160731185556.GA4220@casa.casa> On Sun, Jul 31, 2016 at 06:44:14PM +0000, Ramnath R Iyer wrote: > The program below is what I have working right now (very trivial). I want > to modify this program, so that the `evaluate input` returns not a String, > but a type X that includes information on whether to "continue" and show a > prompt after rendering the result, or exit altogether. So the specific > questions I have here are: > > 1. What would be a sensible type signature for X? Hello Ramnath, as now evaluate *has to* return a String because you pass its output as an argument to outputStrLn (which has a ~ `String -> InputT IO ()` signature itself). A quick hack is for `evaluate` to return evaluate :: String -> (String, Bool) where the Bool stands for 'should I exit or not' (using a datatype and/or a type synonym would be better and more clear). You can then write let (s, b) = evaluate input outputStrLn $ "Something " ++ s if b then loop else exit Your code has a very distinct imperative flavour (there are ways to get rid of that case/if cascade), but my opinion is: first make it work, then make it pretty. Does that help? -F From rri at silentyak.com Sun Jul 31 21:17:09 2016 From: rri at silentyak.com (Ramnath R Iyer) Date: Sun, 31 Jul 2016 21:17:09 +0000 Subject: [Haskell-beginners] Maybe Return? In-Reply-To: <20160731185556.GA4220@casa.casa> References: <20160731185556.GA4220@casa.casa> Message-ID: Hi Francesco, Thank you for your response, it definitely helped. Below is an updated version of working code. Where I was getting tripped up earlier was in the commented portion below. Also, if you scroll down further, I have a few further questions. Thank you for your time. module Main where import Evaluator import System.Console.Haskeline main :: IO () main = runInputT defaultSettings loop where loop :: InputT IO () loop = do line <- getInputLine ">> " case line of Nothing -> return () Just input -> do let (result, next) = evaluate input if (next == Return) then return () else (emit result >> loop) -- I had wanted the result to be emitted only on Continue, not Return. This works, but is it a good way? emit :: Maybe String -> InputT IO () emit Nothing = return () emit (Just value) = outputStrLn $ "Executing: " ++ value module Evaluator where data Next = Continue | Return deriving (Eq, Ord) evaluate :: String -> (Maybe String, Next) -- Now updated to make the first part of the tuple a Maybe String instead of String evaluate "quit" = (Nothing, Return) evaluate value = (Just value, Continue) ** QUESTIONS ** 1. If I wanted to write the logic encapsulated in `emit' directly within main, how would I do that? In my example, I was forced to extract it out as a separate method specifically to leverage pattern matching. 2. You mentioned outputStrLn has a type `String -> InputT IO ()'. How do you logically come to this conclusion? Is it because outputStrLn was taking a single String argument and had to return the same type returned by loop declared previously? 3. Are there better/simpler/more idiomatic ways of structuring my program? On Sun, Jul 31, 2016 at 12:01 PM Francesco Ariis wrote: > On Sun, Jul 31, 2016 at 06:44:14PM +0000, Ramnath R Iyer wrote: > > The program below is what I have working right now (very trivial). I want > > to modify this program, so that the `evaluate input` returns not a > String, > > but a type X that includes information on whether to "continue" and show > a > > prompt after rendering the result, or exit altogether. So the specific > > questions I have here are: > > > > 1. What would be a sensible type signature for X? > > Hello Ramnath, > > as now evaluate *has to* return a String because you pass its output as > an argument to outputStrLn (which has a ~ `String -> InputT IO ()` > signature itself). > > A quick hack is for `evaluate` to return > > evaluate :: String -> (String, Bool) > > where the Bool stands for 'should I exit or not' (using a datatype > and/or a type synonym would be better and more clear). > You can then write > > let (s, b) = evaluate input > outputStrLn $ "Something " ++ s > if b then loop > else exit > > Your code has a very distinct imperative flavour (there are ways > to get rid of that case/if cascade), but my opinion > is: first make it work, then make it pretty. > > Does that help? > -F > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Sun Jul 31 21:51:32 2016 From: fa-ml at ariis.it (Francesco Ariis) Date: Sun, 31 Jul 2016 23:51:32 +0200 Subject: [Haskell-beginners] Maybe Return? In-Reply-To: References: <20160731185556.GA4220@casa.casa> Message-ID: <20160731215132.GA7397@casa.casa> On Sun, Jul 31, 2016 at 09:17:09PM +0000, Ramnath R Iyer wrote: > Below is an updated version of working code. > [...] Well done! Now, to the questions: > 1. If I wanted to write the logic encapsulated in `emit' directly within > main, how would I do that? In my example, I was forced to extract it out as > a separate method specifically to leverage pattern matching. Pattern matching can be done via a `case` statement as well (and you provide an example of this just a few lines above the `emit` call). Personally, I much a prefer separate function as it is clearer (if you don't want to clutter top level use a `where` statement). > 2. You mentioned outputStrLn has a type `String -> InputT IO ()'. How do > you logically come to this conclusion? Is it because outputStrLn was taking > a single String argument and had to return the same type returned by loop > declared previously? Correct, if we ask ghci about `ouputStrLn` it will reply: λ> :t outputStrLn outputStrLn :: Control.Monad.IO.Class.MonadIO m => String -> InputT m () but in this case you have written the signature to `loop` (it's always a good habit), so it's clear our function can only have this concrete data type. > 3. Are there better/simpler/more idiomatic ways of structuring my program? Yes there are: your program checks/pattern matches at every step and for each of those you have a case/if; it could get pretty messy if you were to add a few more actions. There is a nice way to handle these kind of situations, it involves monadic code. But before using monads you need to digest them! So keep following your course (if you are not following any, I like these two, which are gratis [1] [2]) and come back to this .hs after you tamed the mighty monad to refactor it! [1] http://learnyouahaskell.com/ [2] https://www.seas.upenn.edu/~cis194/spring13/lectures.html