From dan9131 at gmail.com Mon Jun 1 10:11:54 2015 From: dan9131 at gmail.com (Dananji Liyanage) Date: Mon, 1 Jun 2015 15:41:54 +0530 Subject: [Haskell-beginners] Command line interface programming Message-ID: Hi All, I'm in the process of learning Haskell, and I need to write a command line interface program which can interact with the user. Right now, I have a sample program written using 'System.Console.Haskeline' package. Can someone please give me some additional material, which I can read on with respect to this? Thanks in advance! -- Regards, Dananji Liyanage -------------- next part -------------- An HTML attachment was scrubbed... URL: From ahammel87 at gmail.com Mon Jun 1 16:10:47 2015 From: ahammel87 at gmail.com (Alex Hammel) Date: Mon, 01 Jun 2015 16:10:47 +0000 Subject: [Haskell-beginners] best way to code this~~ In-Reply-To: <20150531080229.5e520739@cedar.deldotd.com> References: <20150530183044.400cb10b@cedar.deldotd.com> <20150531080229.5e520739@cedar.deldotd.com> Message-ID: > > > f as alist = [ b | (a, b) <- alist, a `elem` as ] > > > > perhaps? > > perhaps. i have no idea how that works. but don't spoil it for me > though, i'm going to go of and study it :-) > It's a list comprehension . I hope that's not too much of a spoiler :) > unsure what the ~(ts, fs) syntax is though, removing the `~` doesn't seem > to matter. > Makes it lazier > > this seems fairly clean. i noticed that partition simply uses foldr. it > looks like select is just a helper so that partition isn't cluttered. i'm > unsure why select was broken out as a separate function instead of just > being in a where clause. possibly to be able to assign it a an explicit > type signature ? > You can assign type signatures in `let` and `where` clauses: f = let i :: Int i = 1 in increment i where increment :: Int -> Int increment = (+) 1 This is often quite a good idea. Type signatures are excellent, machine-checkable documentation. > extract :: [(String,b)] -> [String] -> ([b], [String]) > extract alist l = > let inList s = lookup (uppercase s) alist > (l1, l2) = partitionMaybe inList l > in > (l1, l2) > > partitionMaybe :: (a -> Maybe b) -> [a] -> ([b],[a]) > partitionMaybe p xs = foldr (select p) ([],[]) xs > > select :: (a -> Maybe b) -> a -> ([b], [a]) -> ([b], [a]) > select p x ~(ts,fs) | isJust y = ((fromJust y):ts,fs) > | otherwise = (ts, x:fs) > where > y = p x > Couple of things: `fromJust` is a code smell. In general, you should at least consider replacing it with `fromMaybe (error msg)` where `msg` is a more useful error message than '*** Exception: Maybe.fromJust: Nothing'. Of course in this particular case, that will never come up because you can prove that `y` is never Nothing using the guard condition. But in that case, it's better practice to use pattern matching and let the compiler prove it for you: select p y ~(xs,ys) = acc $ p y where acc (Just x) = (x:xs, ys) acc Nothing = ( xs, y:ys) The `partitionMaybe` function looks a bit odd to me. The computation you're trying to express is 'If this computation succedes, return whatever value it returned, but if it fails return some default value'. This is not a natural use of the Maybe data type: that's what Either is for. There's even a `partitionEithers` library function. `lookup` returns Maybe, not Either, but we can fix that. Here's my go (I've changed around the API a little bit as well) toEither :: a -> (Maybe b) -> Either a b toEither _ (Just x) = Right x toEither y Nothing = Left y lookupEither :: Eq a => a -> [(a,b)] -> Either a b lookupEither key assocs = toEither key $ lookup key assocs uppercase :: String -> String uppercase = map toUpper extract :: [String] -> [(String,b)] -> ([String],[b]) extract xs assocs = let xs' = map uppercase xs eithers = map (\x -> lookupEither x assocs) xs' -- spoilers: same as [ lookupEither x assocs | x <- xs' ] in partitionEithers eithers main :: IO ()main = print $ extract ["Foo", "Bar"] [("FOO",1), ("BAZ",2)] This differs slightly from your algorithm in that it returns '(["BAR"],[1]), where yours would return (["Bar"],[1]). If preserving the original case in the output, I would either write a `caseInsensitiveLookup` function, or use a case insensitive text data type. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hjgtuyl at chello.nl Mon Jun 1 16:56:51 2015 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Mon, 01 Jun 2015 18:56:51 +0200 Subject: [Haskell-beginners] Command line interface programming In-Reply-To: References: Message-ID: On Mon, 01 Jun 2015 12:11:54 +0200, Dananji Liyanage wrote: > Right now, I have a sample program written using > 'System.Console.Haskeline' > package. > > Can someone please give me some additional material, which I can read on > with respect to this? You could look at the reverse dependencies for Haskeline: http://packdeps.haskellers.com/reverse/haskeline 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 kc1956 at gmail.com Mon Jun 1 20:17:07 2015 From: kc1956 at gmail.com (KC) Date: Mon, 1 Jun 2015 13:17:07 -0700 Subject: [Haskell-beginners] I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? Message-ID: I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? That is, to use myArray [5] and have a DSL convert it to standard Haskell syntax -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey -------------- next part -------------- An HTML attachment was scrubbed... URL: From kc1956 at gmail.com Mon Jun 1 20:29:27 2015 From: kc1956 at gmail.com (KC) Date: Mon, 1 Jun 2015 13:29:27 -0700 Subject: [Haskell-beginners] [Haskell-cafe] I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? In-Reply-To: References: Message-ID: Then a tuple might work better as input to a function to index into an array e.g. myArray (5) -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey On Jun 1, 2015 1:21 PM, "Tikhon Jelvis" wrote: > You could make myArray a function that takes a list as an input. Of > course, all your other array functions have to account for this too. A > potential advantage is that this approach leaves the underlying array type > abstract, so you could mix and match different data structure on the > backend. (IntMap, Array, Vector? etc.) > > A disadvantage is that this is non-standard usage which could be confusing > to people and there's no way I know of to statically ensure the list passed > in always had one element. That is, myArray [1, 2] would be legal and > result in a runtime error. > > I don't know of a way to do it while using a normal array type directly. > > On Mon, Jun 1, 2015 at 1:17 PM, KC wrote: > >> I think someone had a complicated program to use brackets for array >> indexing - is it possible to use a DSL for this? >> >> That is, to use myArray [5] and have a DSL convert it to standard Haskell >> syntax >> >> -- >> -- >> >> Sent from an expensive device which will be obsolete in a few months! :D >> >> Casey >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Mon Jun 1 20:35:40 2015 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 1 Jun 2015 16:35:40 -0400 Subject: [Haskell-beginners] [Haskell-cafe] I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? In-Reply-To: References: Message-ID: On Mon, Jun 1, 2015 at 4:29 PM, KC wrote: > Then a tuple might work better as input to a function to index into an > array > > e.g. myArray (5) > Aside from 1-tuples not being a thing? (That's the same as (myArray 5).) -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From kc1956 at gmail.com Mon Jun 1 20:56:45 2015 From: kc1956 at gmail.com (KC) Date: Mon, 1 Jun 2015 13:56:45 -0700 Subject: [Haskell-beginners] [Haskell-cafe] I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? In-Reply-To: References: Message-ID: I'm a part time tutor even though I don't look Elizabethan I was trying to lower the learning curve for students Maybe I'll point them to http://dev.stephendiehl.com/hask/ And Data.Vector -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey On Jun 1, 2015 1:35 PM, "Brandon Allbery" wrote: > On Mon, Jun 1, 2015 at 4:29 PM, KC wrote: > >> Then a tuple might work better as input to a function to index into an >> array >> >> e.g. myArray (5) >> > > Aside from 1-tuples not being a thing? (That's the same as (myArray 5).) > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kc1956 at gmail.com Tue Jun 2 01:00:33 2015 From: kc1956 at gmail.com (KC) Date: Mon, 1 Jun 2015 18:00:33 -0700 Subject: [Haskell-beginners] [Haskell-cafe] I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? In-Reply-To: References: <6c63502aa89eb85e6802c5402d019fe0.squirrel@chasm.otago.ac.nz> Message-ID: On Jun 1, 2015 5:52 PM, "Tikhon Jelvis" wrote: If you teach them about how operators are normal functions in Haskell, using an operator to index into an array makes the indexing operation less magical?a big pedagogical boon, in my view. The fewer special cases in the language you're teaching, the better, and looking similar to other languages is not a good reason for a special case. Especially since the similarity could be misleading!) Good point (s) -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey -------------- next part -------------- An HTML attachment was scrubbed... URL: From cma at bitemyapp.com Tue Jun 2 01:06:42 2015 From: cma at bitemyapp.com (Christopher Allen) Date: Mon, 1 Jun 2015 20:06:42 -0500 Subject: [Haskell-beginners] [Haskell-cafe] I think someone had a complicated program to use brackets for array indexing - is it possible to use a DSL for this? In-Reply-To: References: <6c63502aa89eb85e6802c5402d019fe0.squirrel@chasm.otago.ac.nz> Message-ID: Strongly agreed with ok and Tikhon. I've tried these weird pidgins and localized fabrications wrapped around Haskell before, it's only a stumbling block. Haskell is simple, you don't have to lie - just encourage them not to draw false analogies. On Mon, Jun 1, 2015 at 7:52 PM, Tikhon Jelvis wrote: > If you teach them about how operators are normal functions in Haskell, > using an operator to index into an array makes the indexing operation less > magical?a big pedagogical boon, in my view. The fewer special cases in the > language you're teaching, the better, and looking similar to other > languages is not a good reason for a special case. > > Especially since the similarity could be misleading!) > > On Mon, Jun 1, 2015 at 5:48 PM, wrote: > >> > I'm a part time tutor even though I don't look Elizabethan >> > >> > I was trying to lower the learning curve for students >> >> Using square brackets for array indexing in Haskell >> would be more a case of putting a stumbling block in >> their way than lowering the learning curve. >> >> Fortran uses A(I), not A[I], and has for the last fifty-some >> years. The official definition of Simula 67 uses A(I) as >> well, despite its predecessor Algol 60 using a[i]. COBOL >> uses A(I), and has done so nearly as long as Fortran. PL/I >> (yes, it still exists) uses A(I), not A[I]. BASIC uses >> A(I), this is still so in Visual Basic.NET. If memory >> serves me correctly, MINITAB uses parentheses, not brackets. >> >> Is a pattern beginning to emerge? >> >> Lying to the students by implicitly telling them "all programming >> languages use square brackets for array indexing" will be doing >> them no favour. Even lying about Haskell is no kindness. >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From briand at aracnet.com Tue Jun 2 03:35:57 2015 From: briand at aracnet.com (briand at aracnet.com) Date: Mon, 1 Jun 2015 20:35:57 -0700 Subject: [Haskell-beginners] best way to code this~~ In-Reply-To: References: <20150530183044.400cb10b@cedar.deldotd.com> <20150531080229.5e520739@cedar.deldotd.com> Message-ID: <20150601203557.23b33924@cedar.deldotd.com> On Mon, 01 Jun 2015 16:10:47 +0000 Alex Hammel wrote: Thank you so much for all the info ! Really appreciate it. > extract :: [String] -> [(String,b)] -> ([String],[b]) > extract xs assocs = > let xs' = map uppercase xs > eithers = map (\x -> lookupEither x assocs) xs' > -- spoilers: same as [ lookupEither x assocs | x <- xs' ] > in partitionEithers eithers > > This differs slightly from your algorithm in that it returns > '(["BAR"],[1]), where yours would return (["Bar"],[1]). If preserving > the original case in the output, I would either write a ok. big surprise, i like your version much better. however, i'm unclear why you didn't just use eithers = map (\x -> lookupEither (uppercase x) assocs) xs instead of mapping everything to uppercase first. meanwhile i need to get with the list comprehension program. i use python list comprehensions all the time, and yet i continue to use map in haskell. how weird is that ? Brian From martin at vlkk.cz Tue Jun 2 10:51:41 2015 From: martin at vlkk.cz (Martin Vlk) Date: Tue, 02 Jun 2015 10:51:41 +0000 Subject: [Haskell-beginners] How to use trigonometric functions with Data.Scientific? Message-ID: <556D8ABD.2070108@vlkk.cz> Hi, I am writing a program to do some astronomical calculation, and I am using the Data.Scientific library to represent my floating point numbers. Would anyone know how to use trigonometric functions with the Scientific type? I see: a :: Scientific a = scientific 500036 (-5) sin :: Floating a => a -> a -- this won't work wrongType = sin a Any ideas? Many Thanks Martin From ahammel87 at gmail.com Tue Jun 2 15:49:06 2015 From: ahammel87 at gmail.com (Alex Hammel) Date: Tue, 02 Jun 2015 15:49:06 +0000 Subject: [Haskell-beginners] best way to code this~~ In-Reply-To: <20150601203557.23b33924@cedar.deldotd.com> References: <20150530183044.400cb10b@cedar.deldotd.com> <20150531080229.5e520739@cedar.deldotd.com> <20150601203557.23b33924@cedar.deldotd.com> Message-ID: Thank you so much for all the info ! Really appreciate it. > My pleasure! however, i'm unclear why you didn't just use > > eithers = map (\x -> lookupEither (uppercase x) assocs) xs > > instead of mapping everything to uppercase first. > Two reasons: 1) I thought it would be slightly more readable. 2) There's no performance penalty. My version looks like it traverses the list twice, but it doesn't because laziness. Where the compiler for a strict language might make an intermediate, uppercased list, Haskell will produce the uppercase values as they are needed. To prove that to myself, I ran a quick criterion benchmark. If anything, inlining the call to uppercase *decreases* performance slightly. Incidentally, that's the same reason why the `filterMap` function you asked about earlier doesn't exist. You can just do `(map f . filter p) xs`. The values will be created lazily, with no intermediate list. > > meanwhile i need to get with the list comprehension program. i use python > list comprehensions all the time, and yet i continue to use map in haskell. > how weird is that ? > Not super weird. In my experience listcomps (and their relatives) are much more common in idiomatic Python than idiomatic Haskell. Still something you'll want to know how to do, though. Think '|' = 'for', '<-' = 'in' and ',' = 'if' and you'll be fine. -------------- next part -------------- An HTML attachment was scrubbed... URL: From toad3k at gmail.com Tue Jun 2 18:57:17 2015 From: toad3k at gmail.com (David McBride) Date: Tue, 2 Jun 2015 14:57:17 -0400 Subject: [Haskell-beginners] How to use trigonometric functions with Data.Scientific? In-Reply-To: <556D8ABD.2070108@vlkk.cz> References: <556D8ABD.2070108@vlkk.cz> Message-ID: You should be able to use sin (toRealFloat a). But I imagine that could introduce some error into your calculations. You will have to make sure you put enough type signatures to infer Double. On Tue, Jun 2, 2015 at 6:51 AM, Martin Vlk wrote: > Hi, I am writing a program to do some astronomical calculation, and I am > using the Data.Scientific library to represent my floating point > numbers. Would anyone know how to use trigonometric functions with the > Scientific type? > > I see: > a :: Scientific > a = scientific 500036 (-5) > > sin :: Floating a => a -> a > > -- this won't work > wrongType = sin a > > Any ideas? > > Many Thanks > Martin > _______________________________________________ > 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 briand at aracnet.com Wed Jun 3 04:53:04 2015 From: briand at aracnet.com (briand at aracnet.com) Date: Tue, 2 Jun 2015 21:53:04 -0700 Subject: [Haskell-beginners] best way to code this~~ In-Reply-To: References: <20150530183044.400cb10b@cedar.deldotd.com> <20150531080229.5e520739@cedar.deldotd.com> <20150601203557.23b33924@cedar.deldotd.com> Message-ID: <20150602215304.632a02ba@cedar.deldotd.com> On Tue, 02 Jun 2015 15:49:06 +0000 Alex Hammel wrote: > My version looks like it traverses the list twice, but it doesn't because > laziness. Where the compiler for a strict language might make an > intermediate, uppercased list, Haskell will produce the uppercase values as > they are needed. ok that's cool to know. that's why i like going over these "simple" examples. in thinking about my problem i realized that it's perfectly fine if the uneaten list comes back upper case. so i went back to the map version. actually the list comp version :-) > > Incidentally, that's the same reason why the `filterMap` function you asked > about earlier doesn't exist. You can just do `(map f . filter p) xs`. The > values will be created lazily, with no intermediate list. precisely what i was wondering. haven't tried out criterion yet, just installed it to try out. seems like a valuable learning tool. should be a good learning tool. Brian From martin at vlkk.cz Wed Jun 3 13:23:45 2015 From: martin at vlkk.cz (Martin Vlk) Date: Wed, 03 Jun 2015 13:23:45 +0000 Subject: [Haskell-beginners] How to use trigonometric functions with Data.Scientific? In-Reply-To: References: <556D8ABD.2070108@vlkk.cz> Message-ID: <556EFFE1.3030003@vlkk.cz> David McBride: > You should be able to use sin (toRealFloat a). But I imagine that could > introduce some error into your calculations. You will have to make sure > you put enough type signatures to infer Double. > Hi David, many thanks for your reply. In the end I found the problem was not in precision, but rather a much more mundane mistake - I failed to notice the trigonometric functions expect input value in radians, not degrees. Doh! :-) Now my calculation works as expected. Thanks again Martin From 4bea6c869366227b879ffe4abad50c at gmail.com Thu Jun 4 19:16:37 2015 From: 4bea6c869366227b879ffe4abad50c at gmail.com (Csaba Marosi) Date: Thu, 4 Jun 2015 19:16:37 +0000 Subject: [Haskell-beginners] parallel map/filter Message-ID: Hi, I'm trying to use parallelism in Haskell, parMap in particular. My code is essentially this: import Control.Parallel.Strategies slow :: String -> (String, [Int]) fast x = (x, [0..255]) main :: IO () main = do content <- readFile "4.txt" --a 327 lines long file print $ parMap rpar slow $ lines content For the full/compiling code, see: https://github.com/csmarosi/cryptopals/blob/bf1ca794f897858f9008fb8740a1c3ef1997482b/s01p04.hs What do I miss here? The code should be trivial to run on multiple cores, but it seem to use only a single CPU core, i.e. $ ghc -O2 -v0 -threaded --make s01p04.hs slow gives: $ time ./s01p04 +RTS -N2 | wc 1 1 64028 real 0m8.903s user 0m7.888s sys 0m1.792s whereas fast is: $ time ./s01p04 +RTS -N2 | wc 1 1 320787 real 0m0.016s user 0m0.012s sys 0m0.012s Bonus question: is there a parallel filter? I use Debian sid packages, ghc version 7.8.4 Some multi-threading seems to go on, since without -N2, the sys time is below 0.1s. BTW, the slow code use ~300K heap according to valgrind. Thanks, Csabi From sourabh.s.joshi at gmail.com Thu Jun 4 22:50:25 2015 From: sourabh.s.joshi at gmail.com (Sourabh) Date: Thu, 4 Jun 2015 15:50:25 -0700 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. Message-ID: Hello all! I am trying to solve the following problem on HackerRank. It asks us to compute a cellular automata based on a binary tree: https://www.hackerrank.com/challenges/the-tree-of-life I have got 9/10 test cases passing. The last test case times out on the server. But I was able to download the input and expected output, and verify that it is functionally correct. The problem is that the big input is supposed to run within 5 sec, and mine is taking 145 seconds, LOL! Here was my first implementation: https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/Recursion/cellular_automata_functionally_correct.hs I figured out that I am constantly re-computing the trees, and decided to try and memoize the results. Here is my memoization attempt: https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/Recursion/cellular_automata_memoize_attempt.hs Basically I have changed the simulateCellularAutomata function, which computed the new trees, into a list (automataTrees - line 60). I was expecting the results to be memoized, but the runtime is unchanged. I was wondering if someone can help me figure out what I'm doing wrong with the memoization. Or suggest other ways to memoize this perhaps? -- Thanks much! SSJ -------------- next part -------------- An HTML attachment was scrubbed... URL: From hjgtuyl at chello.nl Thu Jun 4 23:28:30 2015 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Fri, 05 Jun 2015 01:28:30 +0200 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. In-Reply-To: References: Message-ID: On Fri, 05 Jun 2015 00:50:25 +0200, Sourabh wrote: > I figured out that I am constantly re-computing the trees, and decided to > try and memoize the results. Here is my memoization attempt: > https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/Recursion/cellular_automata_memoize_attempt.hs > > Basically I have changed the simulateCellularAutomata function, which > computed the new trees, into a list (automataTrees - line 60). I was > expecting the results to be memoized, but the runtime is unchanged. At a glance: maybe if you change the line automataTrees starttree rule = (starttree) : [ simulateAutomataStep Nothing rule ((automataTrees starttree rule) !! (n-1)) | n <- [1..]] to automataTrees starttree rule = iterate (simulateAutomataStep Nothing rule) starttree it will run faster. The function 'iterate' can be found in Prelude and Data.List. 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 sourabh.s.joshi at gmail.com Thu Jun 4 23:31:07 2015 From: sourabh.s.joshi at gmail.com (Sourabh) Date: Thu, 4 Jun 2015 16:31:07 -0700 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. In-Reply-To: References: Message-ID: Wow, it runs in 0.44 seconds now. This is incredible! Can you explain what just happened here? On Thu, Jun 4, 2015 at 4:28 PM, Henk-Jan van Tuyl wrote: > On Fri, 05 Jun 2015 00:50:25 +0200, Sourabh > wrote: > > I figured out that I am constantly re-computing the trees, and decided to >> try and memoize the results. Here is my memoization attempt: >> >> https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/Recursion/cellular_automata_memoize_attempt.hs >> >> Basically I have changed the simulateCellularAutomata function, which >> computed the new trees, into a list (automataTrees - line 60). I was >> expecting the results to be memoized, but the runtime is unchanged. >> > > At a glance: maybe if you change the line > automataTrees starttree rule = (starttree) : [ simulateAutomataStep > Nothing rule ((automataTrees starttree rule) !! (n-1)) | n <- [1..]] > to > automataTrees starttree rule = iterate (simulateAutomataStep Nothing > rule) starttree > it will run faster. The function 'iterate' can be found in Prelude and > Data.List. > > 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 > -- > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hjgtuyl at chello.nl Fri Jun 5 08:57:45 2015 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Fri, 05 Jun 2015 10:57:45 +0200 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. In-Reply-To: References: Message-ID: 'iterate' uses optimization techniques, see the source code[0][1] (click the 'source' links). I didn't study these techniques in detail. [0] http://haddocks.fpcomplete.com/fp/7.8/20140916-162/base/Prelude.html#v:iterate [1] http://haddocks.fpcomplete.com/fp/7.8/20140916-162/base/GHC-Exts.html#v:build On Fri, 05 Jun 2015 01:31:07 +0200, Sourabh wrote: > Wow, it runs in 0.44 seconds now. This is incredible! Can you explain > what > just happened here? > > On Thu, Jun 4, 2015 at 4:28 PM, Henk-Jan van Tuyl > wrote: > >> On Fri, 05 Jun 2015 00:50:25 +0200, Sourabh >> wrote: >> >> I figured out that I am constantly re-computing the trees, and decided >> to >>> try and memoize the results. Here is my memoization attempt: >>> >>> https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/Recursion/cellular_automata_memoize_attempt.hs >>> >>> Basically I have changed the simulateCellularAutomata function, which >>> computed the new trees, into a list (automataTrees - line 60). I was >>> expecting the results to be memoized, but the runtime is unchanged. >>> >> >> At a glance: maybe if you change the line >> automataTrees starttree rule = (starttree) : [ simulateAutomataStep >> Nothing rule ((automataTrees starttree rule) !! (n-1)) | n <- [1..]] >> to >> automataTrees starttree rule = iterate (simulateAutomataStep Nothing >> rule) starttree >> it will run faster. The function 'iterate' can be found in Prelude and >> Data.List. >> >> 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/ From marcin.jan.mrotek at gmail.com Fri Jun 5 18:38:48 2015 From: marcin.jan.mrotek at gmail.com (Marcin Mrotek) Date: Fri, 5 Jun 2015 20:38:48 +0200 Subject: [Haskell-beginners] parallel map/filter In-Reply-To: References: Message-ID: My first guesses would be that: a) Your program is slowed down because lines from the file is read one line by one, i.e. there's lazy IO at work. Have you tried your code on a list that's loaded in the memory as a whole at once? b) The cost of dereferencing the next link in a list overwhelms the cost of computing one answer. Have you tried using a tree instead? Best regards, Marcin Mrotek -------------- next part -------------- An HTML attachment was scrubbed... URL: From efasckenoth at gmail.com Sat Jun 6 04:01:59 2015 From: efasckenoth at gmail.com (Stefan =?iso-8859-1?Q?H=F6ck?=) Date: Sat, 6 Jun 2015 06:01:59 +0200 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. In-Reply-To: References: Message-ID: <20150606040159.GA5662@hunter.iway.ch> On Thu, Jun 04, 2015 at 04:31:07PM -0700, Sourabh wrote: > Wow, it runs in 0.44 seconds now. This is incredible! Can you explain what > just happened here? Here is a try at an explanation. To reduce the complexity involved with creating automata trees, lets define a very simple function: module Memo () where calc :: Integer -> Integer calc = (1+) And now we build a list of integers in a similar fashion to your tree-generating function: ints :: Integer -> [Integer] ints i = i : [calc (ints i !! (n-1)) | n <- [1..]] Store this in a file, fire up ghci, load the file and enter take 500 $ ints 1 You can literally watch things slowing down as new values are being printed. As you said correctly, at every call to `ints` the whole list is recalculated up to the value you need. Since `ints` is called with a new parameter at every iteration, Haskell has no way of memoizing anything. Let's add some memoization: ints2 :: Integer -> [Integer] ints2 i = let is = i : [calc (is !! (n-1)) | n <- [1..]] in is Again, load this in ghci and run take 500 $ ints2 1 Marvel at the difference. `is` has type [Integer] and as such is a constant. Already calculated values of `is` will therefore be memoized, so the whole list is only created once. Still, this is far from ideal. Enter ints2 1 !! 50000 and wait some more. The problem is that the algorithm still has O(n^2) complexity, n being the length of the list you need to create. At every iteration, `is !! (n-1)` accesses the (n-1)th element of `is` which takes itself n-1 operations. So, to generate a list of ten elements, the algorithm runs is !! 1 is !! 2 . . . is !! 9 to a total of 45 operations. For small list sizes, this makes hardly a difference, but for a list size of 50'000, this means already 1'249'975'000 operations doing nothing but traversing a list. Let's improve this further: ints3 :: Integer -> [Integer] ints3 i = i : ints3 (calc i) Here we use Haskell's lazyness to great effect. This function says: our list of ints is the initial value, prepended to the list of ints starting at the next value. take 500 $ ints3 1 and ints3 1 !! 50000 are both very fast. Every item in the list is calculated exactly once and the algorithm runs in linear time. Now you will only run into trouble at very large indices (above 10'000'000 on my computer). `ints3` is not tail recursive and will produce a stack overflow for very large lists. When you look at the source code of `iterate` you will see that it is just a generalized version of `ints3` taking an additional higher order function as input. I hope this sheds some light Stefan From ky3 at atamo.com Sat Jun 6 05:18:28 2015 From: ky3 at atamo.com (Kim-Ee Yeoh) Date: Sat, 6 Jun 2015 12:18:28 +0700 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. In-Reply-To: <20150606040159.GA5662@hunter.iway.ch> References: <20150606040159.GA5662@hunter.iway.ch> Message-ID: On Sat, Jun 6, 2015 at 11:01 AM, Stefan H?ck wrote: > I hope this sheds some light Marvellous! Thank you for taking the time to break it down usefully into memoization and unnecessary list traversal. -- Kim-Ee -------------- next part -------------- An HTML attachment was scrubbed... URL: From raabe at froglogic.com Sat Jun 6 09:36:25 2015 From: raabe at froglogic.com (Frerich Raabe) Date: Sat, 06 Jun 2015 11:36:25 +0200 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata. In-Reply-To: <20150606040159.GA5662@hunter.iway.ch> References: <20150606040159.GA5662@hunter.iway.ch> Message-ID: <4cc87fad10ecfc5a8980851c8d3ab204@roundcube.froglogic.com> On 2015-06-06 06:01, Stefan H?ck wrote: > On Thu, Jun 04, 2015 at 04:31:07PM -0700, Sourabh wrote: >> Wow, it runs in 0.44 seconds now. This is incredible! Can you explain what >> just happened here? > > Here is a try at an explanation. Thank you a lot for taking the time to walk through it! One thing got me thinking though: > And now we build a list of integers in a similar fashion to your > tree-generating function: > > ints :: Integer -> [Integer] > ints i = i : [calc (ints i !! (n-1)) | n <- [1..]] > > Store this in a file, fire up ghci, load the file and enter > > take 500 $ ints 1 [..] > Let's add some memoization: > > ints2 :: Integer -> [Integer] > ints2 i = let is = i : [calc (is !! (n-1)) | n <- [1..]] > in is > > Again, load this in ghci and run > > take 500 $ ints2 1 > > Marvel at the difference. This is what's known as 'Tying the Knot' (e.g. on https://wiki.haskell.org/Tying_the_Knot), right? I wonder - would it be possible (and plausible) for a compiler to perform this rewriting automatically, such that any occurrence of code like f x = e where 'e' involves a call to 'f x' gets replaced with f x = let z = e in z and all occurences of 'f x' in 'e' get replaced with 'z'? -- Frerich Raabe - raabe at froglogic.com www.froglogic.com - Multi-Platform GUI Testing From mike_k_houghton at yahoo.co.uk Sat Jun 6 18:43:45 2015 From: mike_k_houghton at yahoo.co.uk (Mike Houghton) Date: Sat, 6 Jun 2015 19:43:45 +0100 Subject: [Haskell-beginners] Config data Message-ID: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> Hi, I?ve haskell files parser.hs and email.hs email.hs is a module imported into parser and parser has the main. email has various passwords and server names needed to connect and send email. I want to have those details in a config file and read it in at start - using say config module. I?m ok with this part but the practicality of doing it eludes me... It seems to me that email module can either get the config details itself or be told them by parser. If email wants to get them how would it do this? It does not have a main that gets run so can?t load a config file.(can it ??) However parser can load the config in its main and then tell mail what the values are but how would mail save them? Of course I could chanage the signatures of the email send/receive functions in mail to take the connection details but that seems wrong. Thanks Mike From sumit.sahrawat.apm13 at iitbhu.ac.in Sat Jun 6 18:45:27 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Sun, 7 Jun 2015 00:15:27 +0530 Subject: [Haskell-beginners] Config data In-Reply-To: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> Message-ID: It would me more logical if you had three modules, Parser, EMail, Main, where Main imports the other two, and they are independent. On 7 June 2015 at 00:13, Mike Houghton wrote: > Hi, > > I?ve haskell files parser.hs and email.hs > email.hs is a module imported into parser and parser has the main. > > email has various passwords and server names needed to connect and send > email. I want to have those details in a config file and read it in at > start - using say config module. I?m ok with this part but the > practicality of doing it eludes me... > > It seems to me that email module can either get the config details itself > or be told them by parser. If email wants to get them how would it do this? > It does not have a main that gets run so can?t load a config file.(can it > ??) > > However parser can load the config in its main and then tell mail what the > values are but how would mail save them? > > Of course I could chanage the signatures of the email send/receive > functions in mail to take the connection details but that seems wrong. > > Thanks > > Mike > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From sumit.sahrawat.apm13 at iitbhu.ac.in Sat Jun 6 18:49:52 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Sun, 7 Jun 2015 00:19:52 +0530 Subject: [Haskell-beginners] Config data In-Reply-To: References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> Message-ID: You can save the values inside the EMail module at startup using a global variable, but that is not recommended. ( https://wiki.haskell.org/Top_level_mutable_state) On 7 June 2015 at 00:15, Sumit Sahrawat, Maths & Computing, IIT (BHU) < sumit.sahrawat.apm13 at iitbhu.ac.in> wrote: > It would me more logical if you had three modules, Parser, EMail, Main, > where Main imports the other two, and they are independent. > > On 7 June 2015 at 00:13, Mike Houghton > wrote: > >> Hi, >> >> I?ve haskell files parser.hs and email.hs >> email.hs is a module imported into parser and parser has the main. >> >> email has various passwords and server names needed to connect and send >> email. I want to have those details in a config file and read it in at >> start - using say config module. I?m ok with this part but the >> practicality of doing it eludes me... >> >> It seems to me that email module can either get the config details itself >> or be told them by parser. If email wants to get them how would it do this? >> It does not have a main that gets run so can?t load a config file.(can it >> ??) >> >> However parser can load the config in its main and then tell mail what >> the values are but how would mail save them? >> >> Of course I could chanage the signatures of the email send/receive >> functions in mail to take the connection details but that seems wrong. >> >> Thanks >> >> Mike >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > > > > -- > Regards > > Sumit Sahrawat > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From mike_k_houghton at yahoo.co.uk Sat Jun 6 19:07:17 2015 From: mike_k_houghton at yahoo.co.uk (mike h) Date: Sat, 6 Jun 2015 19:07:17 +0000 (UTC) Subject: [Haskell-beginners] Config data In-Reply-To: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> Message-ID: <1460553189.8392786.1433617637485.JavaMail.yahoo@mail.yahoo.com> Global state is an option - thanks. Didn't think Haskell allowed this. Having three modules may be more logical but doesn't it just put the same problem into the new module? Thanks On Saturday, 6 June 2015, 19:43, Mike Houghton wrote: Hi, I?ve haskell files? parser.hs and email.hs email.hs is a module imported into parser and parser has the main. email has various passwords and server names needed to connect and send email. I want to have those details in a config file and read it? in at start - using say config module.? I?m ok with this part but the practicality of doing it eludes me... It seems to me that email module can either get the config details itself or be told them by parser. If email wants to get them how would it do this? It does not have a main that gets run so can?t load a config file.(can it ??) However parser can load the config in its main and then tell mail what the values are but how would mail save them? Of course I could chanage the signatures of the email send/receive functions in mail? to take the connection details but that seems wrong. Thanks Mike _______________________________________________ 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 sumit.sahrawat.apm13 at iitbhu.ac.in Sat Jun 6 19:16:32 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Sun, 7 Jun 2015 00:46:32 +0530 Subject: [Haskell-beginners] Config data In-Reply-To: <1460553189.8392786.1433617637485.JavaMail.yahoo@mail.yahoo.com> References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> <1460553189.8392786.1433617637485.JavaMail.yahoo@mail.yahoo.com> Message-ID: Yeah, sorry I missed the last line on my first read. The link I gave you also explains how to achieve the same functionality as global variables without using them. The unsafePerformIO hack works, but for small modules it's much more helpful to do it safely. On 7 June 2015 at 00:37, mike h wrote: > Global state is an option - thanks. Didn't think Haskell allowed this. > > Having three modules may be more logical but doesn't it just put the same > problem into the new module? > > Thanks > > > > On Saturday, 6 June 2015, 19:43, Mike Houghton < > mike_k_houghton at yahoo.co.uk> wrote: > > > Hi, > > I?ve haskell files parser.hs and email.hs > email.hs is a module imported into parser and parser has the main. > > email has various passwords and server names needed to connect and send > email. I want to have those details in a config file and read it in at > start - using say config module. I?m ok with this part but the > practicality of doing it eludes me... > > It seems to me that email module can either get the config details itself > or be told them by parser. If email wants to get them how would it do this? > It does not have a main that gets run so can?t load a config file.(can it > ??) > > However parser can load the config in its main and then tell mail what the > values are but how would mail save them? > > Of course I could chanage the signatures of the email send/receive > functions in mail to take the connection details but that seems wrong. > > Thanks > > Mike > > > _______________________________________________ > 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 > > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From rein.henrichs at gmail.com Sat Jun 6 20:14:50 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Sat, 06 Jun 2015 20:14:50 +0000 Subject: [Haskell-beginners] Config data In-Reply-To: References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> <1460553189.8392786.1433617637485.JavaMail.yahoo@mail.yahoo.com> Message-ID: Can we please not suggest "not recommended" solutions (that most of us probably wouldn't use) without at least providing a recommended alternative? You can parse the config file into a record and then either pass it as an argument wherever it is needed or use Reader (or ReaderT) to make it more implicit. On Sat, Jun 6, 2015 at 12:16 PM Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote: > Yeah, sorry I missed the last line on my first read. > > The link I gave you also explains how to achieve the same functionality as > global variables without using them. > The unsafePerformIO hack works, but for small modules it's much more > helpful to do it safely. > > On 7 June 2015 at 00:37, mike h wrote: > >> Global state is an option - thanks. Didn't think Haskell allowed this. >> >> Having three modules may be more logical but doesn't it just put the same >> problem into the new module? >> >> Thanks >> >> >> >> On Saturday, 6 June 2015, 19:43, Mike Houghton < >> mike_k_houghton at yahoo.co.uk> wrote: >> >> >> Hi, >> >> I?ve haskell files parser.hs and email.hs >> email.hs is a module imported into parser and parser has the main. >> >> email has various passwords and server names needed to connect and send >> email. I want to have those details in a config file and read it in at >> start - using say config module. I?m ok with this part but the >> practicality of doing it eludes me... >> >> It seems to me that email module can either get the config details itself >> or be told them by parser. If email wants to get them how would it do this? >> It does not have a main that gets run so can?t load a config file.(can it >> ??) >> >> However parser can load the config in its main and then tell mail what >> the values are but how would mail save them? >> >> Of course I could chanage the signatures of the email send/receive >> functions in mail to take the connection details but that seems wrong. >> >> Thanks >> >> Mike >> >> >> _______________________________________________ >> 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 >> >> > > > -- > Regards > > Sumit Sahrawat > _______________________________________________ > 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 sumit.sahrawat.apm13 at iitbhu.ac.in Sat Jun 6 20:22:14 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Sun, 7 Jun 2015 01:52:14 +0530 Subject: [Haskell-beginners] Config data In-Reply-To: References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> <1460553189.8392786.1433617637485.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 7 June 2015 at 01:44, Rein Henrichs wrote: > Can we please not suggest "not recommended" solutions (that most of us > probably wouldn't use) without at least providing a recommended alternative? > I wholeheartedly agree. I mentioned that it is not recommended, and gave a link where that point was stressed much better than I could hope to do. A global variable turns out be the most accessible and easy solution, and it provides a good playground to experiment with trying to replace them with something else. -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From shishir.srivastava at gmail.com Sun Jun 7 20:09:06 2015 From: shishir.srivastava at gmail.com (Shishir Srivastava) Date: Sun, 7 Jun 2015 21:09:06 +0100 Subject: [Haskell-beginners] Usage of $ Message-ID: Hi, Can someone please highlight how '$' is making the difference in the execution of this function. With $ in place the function runs fine but without $ for large input values the function overflows the stack. -------- s mp 1 = 4 s mp n = ((s mp $ n-1)^2-2) `mod` mp -------- I cannot understand the difference between (s mp $ n-1) and (s mp n-1) Thanks, Shishir Srivastava +44 (0) 750 127 5019 -------------- next part -------------- An HTML attachment was scrubbed... URL: From mwm at mired.org Sun Jun 7 20:21:26 2015 From: mwm at mired.org (Mike Meyer) Date: Sun, 7 Jun 2015 15:21:26 -0500 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: Message-ID: s mp $ n - 1 parses as s mp (n - 1) s mp n - 1 parses as (s mp n) - 1 On Sun, Jun 7, 2015 at 3:09 PM, Shishir Srivastava < shishir.srivastava at gmail.com> wrote: > Hi, > > Can someone please highlight how '$' is making the difference in the > execution of this function. With $ in place the function runs fine but > without $ for large input values the function overflows the stack. > > -------- > s mp 1 = 4 > s mp n = ((s mp $ n-1)^2-2) `mod` mp > -------- > > I cannot understand the difference between > (s mp $ n-1) and (s mp n-1) > > Thanks, > Shishir Srivastava > +44 (0) 750 127 5019 > > > _______________________________________________ > 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 sourabh.s.joshi at gmail.com Sun Jun 7 21:56:34 2015 From: sourabh.s.joshi at gmail.com (Sourabh) Date: Sun, 7 Jun 2015 14:56:34 -0700 Subject: [Haskell-beginners] Haskell Bin Tree Cellular Automata Message-ID: Thanks for the wonderful post earlier on memoization Stefan. I'm still trying to wrap my head around all the details. For example I'm trying to figure out why (in the second version) the constant "is" scoped within the function isn't garbage collected in between different calls to the function. It seems like there is a lot going on behind the scenes, and even though things look "semantically correct" to a beginner, they aren't so straightforward. :) I think I will re-read your post a couple more time, and hopefully get some more insight. BTW, Sorry I didn't notice your update earlier. For some reason, I only get certain emails from this list, and others disappear down a black hole. I just happened to browse the archives and noticed this response. Is there a web interface or such to browse and/or respond to threads? I just usually mail "beginners at haskell.org" which is a painful way to do this... (unless I'm doing it wrong). -------------- next part -------------- An HTML attachment was scrubbed... URL: From sourabh.s.joshi at gmail.com Sun Jun 7 22:15:16 2015 From: sourabh.s.joshi at gmail.com (Sourabh) Date: Sun, 7 Jun 2015 15:15:16 -0700 Subject: [Haskell-beginners] Dynamic programming (memoization) w/ string keys. Message-ID: Hello again! I'm hoping to get some more insight into another memoization issue I'm facing. This time, I was solving the following problem, which seems like a dynamic programming problem. https://www.hackerrank.com/challenges/game-of-kyles I coded up a straightforward recurrence equation (without any memoization): https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/AdHoc/gameOfKyles_functionallyCorrect.hs The function playGameOfKyles shows the recurrence. (playGameOfKyles :: String -> Bool) I tried to perform top-down dynamic programming, by caching the results in a Data.Map, in between calls to the function. This is because the input is a string. Here is the new version: https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/AdHoc/gameOfKyles_mapMemoized.hs Basically I am passing a map around, and returning one as well. ( playGameOfKyles :: CacheMap -> String -> (Bool, CacheMap)) The naive version (without memoization) is extremely slow of course, and probably won't finish running until the sun cools down (so far, even one test case of a string with length 74 hasn't finished running after many minutes). The memoized version is... improving something... and for example the entire test case 2, which contains 100 test cases of size 50 to 100 each, runs in about 8 minutes. Is there something I can improve with the memoization, to make it faster? Use something other than Data.Map? Or could the bottleneck be someplace else in the algorithm? I know those are kinda broad questions, but I've run out of ideas... -------------- next part -------------- An HTML attachment was scrubbed... URL: From efasckenoth at gmail.com Mon Jun 8 03:45:47 2015 From: efasckenoth at gmail.com (Stefan =?iso-8859-1?Q?H=F6ck?=) Date: Mon, 8 Jun 2015 05:45:47 +0200 Subject: [Haskell-beginners] Dynamic programming (memoization) w/ string keys. In-Reply-To: References: Message-ID: <20150608034547.GA1036@hunter.iway.ch> Do you have a dynamic programming solution which runs reasonably fast in another language? Because this game of kyles looks like an example from combinatoric game theory to me and as such it might be much more efficient to solve it using nim-sums (if possible; I haven't given this too much thought). Also note that, since your strings only consist of X and I, you could also use Integers and bit-operations instead of lists in your algorithms. You'd still need a Map for memoization, but other operations might be much faster. Cheers Stefan On Sun, Jun 07, 2015 at 03:15:16PM -0700, Sourabh wrote: > Hello again! I'm hoping to get some more insight into another memoization > issue I'm facing. > > This time, I was solving the following problem, which seems like a dynamic > programming problem. > https://www.hackerrank.com/challenges/game-of-kyles > > I coded up a straightforward recurrence equation (without any memoization): > https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/AdHoc/gameOfKyles_functionallyCorrect.hs > > > The function playGameOfKyles shows the recurrence. (playGameOfKyles :: > String -> Bool) > > I tried to perform top-down dynamic programming, by caching the results in > a Data.Map, in between calls to the function. This is because the input is > a string. > > Here is the new version: > https://github.com/cbrghostrider/Hacking/blob/master/HackerRank/FunctionalProgramming/AdHoc/gameOfKyles_mapMemoized.hs > > Basically I am passing a map around, and returning one as well. ( > playGameOfKyles :: CacheMap -> String -> (Bool, CacheMap)) > > The naive version (without memoization) is extremely slow of course, and > probably won't finish running until the sun cools down (so far, even one > test case of a string with length 74 hasn't finished running after many > minutes). > > The memoized version is... improving something... and for example the > entire test case 2, which contains 100 test cases of size 50 to 100 each, > runs in about 8 minutes. > > Is there something I can improve with the memoization, to make it faster? > Use something other than Data.Map? Or could the bottleneck be someplace > else in the algorithm? I know those are kinda broad questions, but I've run > out of ideas... > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From martin at vlkk.cz Mon Jun 8 10:01:18 2015 From: martin at vlkk.cz (Martin Vlk) Date: Mon, 08 Jun 2015 10:01:18 +0000 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: Message-ID: <557567EE.10202@vlkk.cz> Mike Meyer: > s mp $ n - 1 parses as s mp (n - 1) > s mp n - 1 parses as (s mp n) - 1 Hi, I think it is misleading to say that $ "parses" to something. ($) is an infix operator with type: ($) :: (a -> b) -> a -> b -- Defined in ?GHC.Base? infixr 0 $ So what it does is it takes a function on the left hand side and applies it to the second argument on the right hand side. The trick is it has the lowest possible precedence value (0) so everything on the right hand side will be evaluated before applying the function on the left. This is useful as a convenience if you want to avoid writing too many parentheses. Martin From mwm at mired.org Mon Jun 8 10:20:13 2015 From: mwm at mired.org (Mike Meyer) Date: Mon, 8 Jun 2015 05:20:13 -0500 Subject: [Haskell-beginners] Usage of $ In-Reply-To: <557567EE.10202@vlkk.cz> References: <557567EE.10202@vlkk.cz> Message-ID: On Jun 8, 2015 05:01, "Martin Vlk" wrote: > > Mike Meyer: > > s mp $ n - 1 parses as s mp (n - 1) > > s mp n - 1 parses as (s mp n) - 1 > > > Hi, I think it is misleading to say that $ "parses" to something. Which is why I didn't say such a thing. The two sentences show how the expressions he was having trouble with are parsed. > ($) is an infix operator with type: > > ($) :: (a -> b) -> a -> b -- Defined in ?GHC.Base? > infixr 0 $ > > So what it does is it takes a function on the left hand side and applies > it to the second argument on the right hand side. The trick is it has > the lowest possible precedence value (0) so everything on the right hand > side will be evaluated before applying the function on the left. Which explains why the expression containing a $ parses as it does, which is also useful information. -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at vlkk.cz Mon Jun 8 12:31:39 2015 From: martin at vlkk.cz (Martin Vlk) Date: Mon, 08 Jun 2015 12:31:39 +0000 Subject: [Haskell-beginners] cabal install glfw failing Message-ID: <55758B2B.80303@vlkk.cz> Hi, I am trying to install the Euterpea library, which depends on glfw, but it is failing to install with a compilation failure. Could someone take a look at the error and tell me what might be wrong? Many Thanks Martin The Glorious Glasgow Haskell Compilation System, version 7.10.1 cabal-install version 1.22.4.0 using version 1.22.3.0 of the Cabal library $ cabal update $ cabal install glfw Resolving dependencies... Configuring GLFW-0.5.2.2... Failed to install GLFW-0.5.2.2 Build log ( /home/martin/.cabal/logs/GLFW-0.5.2.2.log ): cabal: Error: some packages failed to install: GLFW-0.5.2.2 failed during the configure step. The exception was: user error ('/home/martin/.ghc/bin/ghc' exited with an error: /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:106:14: No instance for (Applicative (StateT ConfState IO)) arising from a use of ?modify? In the expression: modify In the expression: modify $ \ (ConfState fs ls) -> ConfState fs (lib : ls) In an equation for ?addLib?: addLib lib = modify $ \ (ConfState fs ls) -> ConfState fs (lib : ls) /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:242:10: Could not deduce (Applicative (StateT s m)) arising from the superclasses of an instance declaration from the context (Monad m) bound by the instance declaration at /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:242:10-40 In the instance declaration for ?Monad (StateT s m)? /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:252:10: Could not deduce (Applicative (StateT s m)) arising from the superclasses of an instance declaration from the context (Monad m) bound by the instance declaration at /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:252:10-47 In the instance declaration for ?MonadState s (StateT s m)? ) From rein.henrichs at gmail.com Mon Jun 8 17:06:40 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Mon, 08 Jun 2015 17:06:40 +0000 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: The point is that there is no parsing happening here. Just evaluation. On Mon, Jun 8, 2015 at 3:20 AM Mike Meyer wrote: > > On Jun 8, 2015 05:01, "Martin Vlk" wrote: > > > > Mike Meyer: > > > s mp $ n - 1 parses as s mp (n - 1) > > > s mp n - 1 parses as (s mp n) - 1 > > > > > > Hi, I think it is misleading to say that $ "parses" to something. > > Which is why I didn't say such a thing. The two sentences show how the > expressions he was having trouble with are parsed. > > > ($) is an infix operator with type: > > > > ($) :: (a -> b) -> a -> b -- Defined in ?GHC.Base? > > infixr 0 $ > > > > So what it does is it takes a function on the left hand side and applies > > it to the second argument on the right hand side. The trick is it has > > the lowest possible precedence value (0) so everything on the right hand > > side will be evaluated before applying the function on the left. > > Which explains why the expression containing a $ parses as it does, which > is also useful information. > _______________________________________________ > 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 mwm at mired.org Mon Jun 8 18:01:52 2015 From: mwm at mired.org (Mike Meyer) Date: Mon, 8 Jun 2015 13:01:52 -0500 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: Are you saying that GHC doesn't have a haskell parser? On Mon, Jun 8, 2015 at 12:06 PM, Rein Henrichs wrote: > The point is that there is no parsing happening here. Just evaluation. > > On Mon, Jun 8, 2015 at 3:20 AM Mike Meyer wrote: > >> >> On Jun 8, 2015 05:01, "Martin Vlk" wrote: >> > >> > Mike Meyer: >> > > s mp $ n - 1 parses as s mp (n - 1) >> > > s mp n - 1 parses as (s mp n) - 1 >> > >> > >> > Hi, I think it is misleading to say that $ "parses" to something. >> >> Which is why I didn't say such a thing. The two sentences show how the >> expressions he was having trouble with are parsed. >> >> > ($) is an infix operator with type: >> > >> > ($) :: (a -> b) -> a -> b -- Defined in ?GHC.Base? >> > infixr 0 $ >> > >> > So what it does is it takes a function on the left hand side and applies >> > it to the second argument on the right hand side. The trick is it has >> > the lowest possible precedence value (0) so everything on the right hand >> > side will be evaluated before applying the function on the left. >> >> Which explains why the expression containing a $ parses as it does, which >> is also useful information. >> _______________________________________________ >> 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 rein.henrichs at gmail.com Mon Jun 8 19:06:57 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Mon, 08 Jun 2015 19:06:57 +0000 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: Of course not. What a silly thing to suggest. I'm saying that parsing is not relevant to the behavior of ($). The parser can't tell the *semantic* difference between $ and any other operator. On Mon, Jun 8, 2015 at 11:02 AM Mike Meyer wrote: > Are you saying that GHC doesn't have a haskell parser? > > > On Mon, Jun 8, 2015 at 12:06 PM, Rein Henrichs > wrote: > >> The point is that there is no parsing happening here. Just evaluation. >> >> On Mon, Jun 8, 2015 at 3:20 AM Mike Meyer wrote: >> >>> >>> On Jun 8, 2015 05:01, "Martin Vlk" wrote: >>> > >>> > Mike Meyer: >>> > > s mp $ n - 1 parses as s mp (n - 1) >>> > > s mp n - 1 parses as (s mp n) - 1 >>> > >>> > >>> > Hi, I think it is misleading to say that $ "parses" to something. >>> >>> Which is why I didn't say such a thing. The two sentences show how the >>> expressions he was having trouble with are parsed. >>> >>> > ($) is an infix operator with type: >>> > >>> > ($) :: (a -> b) -> a -> b -- Defined in ?GHC.Base? >>> > infixr 0 $ >>> > >>> > So what it does is it takes a function on the left hand side and >>> applies >>> > it to the second argument on the right hand side. The trick is it has >>> > the lowest possible precedence value (0) so everything on the right >>> hand >>> > side will be evaluated before applying the function on the left. >>> >>> Which explains why the expression containing a $ parses as it does, >>> which is also useful information. >>> _______________________________________________ >>> 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 >> >> > _______________________________________________ > 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 mwm at mired.org Mon Jun 8 19:17:43 2015 From: mwm at mired.org (Mike Meyer) Date: Mon, 8 Jun 2015 14:17:43 -0500 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: The OP's problem wasn't with the semantics of $. The OP's problem was that the two expression had different parse trees that gave him different results when evaluated. So not only was there parsing happening here, but it was the root cause of his confusion. Given that the output of GHC's parser was the cause of the confusion, I couldn't think of anything else you might have meant that made sense in context. On Mon, Jun 8, 2015 at 2:06 PM, Rein Henrichs wrote: > Of course not. What a silly thing to suggest. I'm saying that parsing is > not relevant to the behavior of ($). The parser can't tell the *semantic* > difference between $ and any other operator. > On Mon, Jun 8, 2015 at 11:02 AM Mike Meyer wrote: > >> Are you saying that GHC doesn't have a haskell parser? >> On Mon, Jun 8, 2015 at 12:06 PM, Rein Henrichs >> wrote: >> >>> The point is that there is no parsing happening here. Just evaluation. >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From rein.henrichs at gmail.com Mon Jun 8 19:28:50 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Mon, 08 Jun 2015 19:28:50 +0000 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: You said, > s mp $ n - 1 parses as s mp (n - 1) > s mp n - 1 parses as (s mp n) - 1 This is not how they parse. This is how they *evaluate*. A description of how they *parse* would have included the ($) token in a parse tree. This mistake is what lead to our confusion and your rudeness hasn't helped to clarify things. Rather than pretending that we're idiots for not understanding what you meant, it would have been better if you had just said what you meant. On Mon, Jun 8, 2015 at 12:18 PM Mike Meyer wrote: > The OP's problem wasn't with the semantics of $. The OP's problem was that > the two expression had different parse trees that gave him different > results when evaluated. So not only was there parsing happening here, but > it was the root cause of his confusion. > > Given that the output of GHC's parser was the cause of the confusion, I > couldn't think of anything else you might have meant that made sense in > context. > > On Mon, Jun 8, 2015 at 2:06 PM, Rein Henrichs > wrote: > >> Of course not. What a silly thing to suggest. I'm saying that parsing is >> not relevant to the behavior of ($). The parser can't tell the *semantic* >> difference between $ and any other operator. >> On Mon, Jun 8, 2015 at 11:02 AM Mike Meyer wrote: >> >>> Are you saying that GHC doesn't have a haskell parser? >>> On Mon, Jun 8, 2015 at 12:06 PM, Rein Henrichs >>> wrote: >>> >>>> The point is that there is no parsing happening here. Just evaluation. >>>> >>> _______________________________________________ > 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 mwm at mired.org Mon Jun 8 19:30:49 2015 From: mwm at mired.org (Mike Meyer) Date: Mon, 8 Jun 2015 14:30:49 -0500 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: My apologies if I came off as rude. That was not my intent. On Mon, Jun 8, 2015 at 2:28 PM, Rein Henrichs wrote: > You said, > > > s mp $ n - 1 parses as s mp (n - 1) > > s mp n - 1 parses as (s mp n) - 1 > > This is not how they parse. This is how they *evaluate*. A description of > how they *parse* would have included the ($) token in a parse tree. > > This mistake is what lead to our confusion and your rudeness hasn't helped > to clarify things. Rather than pretending that we're idiots for not > understanding what you meant, it would have been better if you had just > said what you meant. > > On Mon, Jun 8, 2015 at 12:18 PM Mike Meyer wrote: > >> The OP's problem wasn't with the semantics of $. The OP's problem was >> that the two expression had different parse trees that gave him different >> results when evaluated. So not only was there parsing happening here, but >> it was the root cause of his confusion. >> >> Given that the output of GHC's parser was the cause of the confusion, I >> couldn't think of anything else you might have meant that made sense in >> context. >> >> On Mon, Jun 8, 2015 at 2:06 PM, Rein Henrichs >> wrote: >> >>> Of course not. What a silly thing to suggest. I'm saying that parsing >>> is not relevant to the behavior of ($). The parser can't tell the >>> *semantic* difference between $ and any other operator. >>> On Mon, Jun 8, 2015 at 11:02 AM Mike Meyer wrote: >>> >>>> Are you saying that GHC doesn't have a haskell parser? >>>> On Mon, Jun 8, 2015 at 12:06 PM, Rein Henrichs >>> > wrote: >>>> >>>>> The point is that there is no parsing happening here. Just evaluation. >>>>> >>>> _______________________________________________ >> 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 rein.henrichs at gmail.com Mon Jun 8 19:36:18 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Mon, 08 Jun 2015 19:36:18 +0000 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: I can't imagine that you actually believed in good faith that I would be confused about whether a Haskell compiler would contain a Haskell parser. On Mon, Jun 8, 2015 at 12:31 PM Mike Meyer wrote: > My apologies if I came off as rude. That was not my intent. > > On Mon, Jun 8, 2015 at 2:28 PM, Rein Henrichs > wrote: > >> You said, >> >> > s mp $ n - 1 parses as s mp (n - 1) >> > s mp n - 1 parses as (s mp n) - 1 >> >> This is not how they parse. This is how they *evaluate*. A description of >> how they *parse* would have included the ($) token in a parse tree. >> >> This mistake is what lead to our confusion and your rudeness hasn't >> helped to clarify things. Rather than pretending that we're idiots for not >> understanding what you meant, it would have been better if you had just >> said what you meant. >> >> On Mon, Jun 8, 2015 at 12:18 PM Mike Meyer wrote: >> >>> The OP's problem wasn't with the semantics of $. The OP's problem was >>> that the two expression had different parse trees that gave him different >>> results when evaluated. So not only was there parsing happening here, but >>> it was the root cause of his confusion. >>> >>> Given that the output of GHC's parser was the cause of the confusion, I >>> couldn't think of anything else you might have meant that made sense in >>> context. >>> >>> On Mon, Jun 8, 2015 at 2:06 PM, Rein Henrichs >>> wrote: >>> >>>> Of course not. What a silly thing to suggest. I'm saying that parsing >>>> is not relevant to the behavior of ($). The parser can't tell the >>>> *semantic* difference between $ and any other operator. >>>> On Mon, Jun 8, 2015 at 11:02 AM Mike Meyer wrote: >>>> >>>>> Are you saying that GHC doesn't have a haskell parser? >>>>> On Mon, Jun 8, 2015 at 12:06 PM, Rein Henrichs < >>>>> rein.henrichs at gmail.com> wrote: >>>>> >>>>>> The point is that there is no parsing happening here. Just >>>>>> evaluation. >>>>>> >>>>> _______________________________________________ >>> 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 >> >> > _______________________________________________ > 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 defigueiredo at ucdavis.edu Mon Jun 8 21:47:00 2015 From: defigueiredo at ucdavis.edu (Dimitri DeFigueiredo) Date: Mon, 08 Jun 2015 15:47:00 -0600 Subject: [Haskell-beginners] grouping functions together Message-ID: <55760D54.2030101@ucdavis.edu> Hello! I am trying to tie together a group of functions that turn an unreliable remote network call into a reliable one. For each different network request I make, a specific group of these functions should always work together, but their type signatures are quite different. My first thought was to put them all in a typeclass: import Control.Monad class Reliable1 m req attempt ack failure result where getRequests1 :: Monad m => m [req] mkAttempt1 :: Monad m => req -> m (Maybe attempt) action1 :: Monad m => attempt -> m (Maybe ack) getAcks1 :: Monad m => [attempt] -> m [ack] mkResult1 :: Monad m => req -> ack -> m (Either failure result) run1 :: Monad m => req -> m result That doesn't work because not all functions use all parameters. For example, getAcks1 has no idea of what the final 'result' type parameter is. This lead me to my second attempt. Defining a 'service' type with the sole purpose of tying them all together. Here's my current attempt: {-# LANGUAGE MultiParamTypeClasses #-} import Control.Monad class Reliable m service where getReqs :: Monad m => service -> m [req] mkAttempt :: Monad m => service -> req -> m (Maybe attempt) action :: Monad m => service -> attempt -> m (Maybe ack) getAcks :: Monad m => service -> [attempt] -> m [ack] mkResult :: Monad m => service -> req -> ack -> m (Either failure result) run :: Monad m => service -> req -> m result data RemoteCall = RemoteCall instance Reliable IO RemoteCall where getReqs = undefined mkAttempt = undefined action = undefined getAcks = undefined mkResult = undefined run = undefined This works, but I have to explicitly pass the 'service' argument in every call. Can I avoid passing this parameter every time? Question, is there a better way to do this? I wanted to have a wrapper to make my remote calls reliable. Thanks, Dimitri From rein.henrichs at gmail.com Mon Jun 8 22:36:27 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Mon, 08 Jun 2015 22:36:27 +0000 Subject: [Haskell-beginners] grouping functions together In-Reply-To: <55760D54.2030101@ucdavis.edu> References: <55760D54.2030101@ucdavis.edu> Message-ID: This seems like a case where you only really need a record, not a typeclass. On Mon, Jun 8, 2015 at 2:47 PM Dimitri DeFigueiredo < defigueiredo at ucdavis.edu> wrote: > Hello! > > I am trying to tie together a group of functions that turn an unreliable > remote network call into a reliable one. For each different network > request I make, a specific group of these functions should always work > together, but their type signatures are quite different. My first > thought was to put them all in a typeclass: > > import Control.Monad > > class Reliable1 m req attempt ack failure result where > getRequests1 :: Monad m => m [req] > mkAttempt1 :: Monad m => req -> m (Maybe attempt) > action1 :: Monad m => attempt -> m (Maybe ack) > getAcks1 :: Monad m => [attempt] -> m [ack] > mkResult1 :: Monad m => req -> ack -> m (Either failure result) > run1 :: Monad m => req -> m result > > That doesn't work because not all functions use all parameters. For > example, getAcks1 has no idea of what the final 'result' type parameter > is. This lead me to my second attempt. Defining a 'service' type with > the sole purpose of tying them all together. Here's my current attempt: > > {-# LANGUAGE MultiParamTypeClasses #-} > > import Control.Monad > > class Reliable m service where > getReqs :: Monad m => service -> m [req] > mkAttempt :: Monad m => service -> req -> m (Maybe attempt) > action :: Monad m => service -> attempt -> m (Maybe ack) > getAcks :: Monad m => service -> [attempt] -> m [ack] > mkResult :: Monad m => service -> req -> ack -> m (Either > failure result) > run :: Monad m => service -> req -> m result > > data RemoteCall = RemoteCall > > instance Reliable IO RemoteCall where > getReqs = undefined > mkAttempt = undefined > action = undefined > getAcks = undefined > mkResult = undefined > run = undefined > > This works, but I have to explicitly pass the 'service' argument in > every call. > Can I avoid passing this parameter every time? > Question, is there a better way to do this? > I wanted to have a wrapper to make my remote calls reliable. > > Thanks, > > Dimitri > > > > _______________________________________________ > 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 sumit.sahrawat.apm13 at iitbhu.ac.in Tue Jun 9 01:45:31 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Tue, 9 Jun 2015 07:15:31 +0530 Subject: [Haskell-beginners] Usage of $ In-Reply-To: References: <557567EE.10202@vlkk.cz> Message-ID: > s mp $ n - 1 parses as s mp (n - 1) > s mp n - 1 parses as (s mp n) - 1 It should be s mp $ n - 1 parses as ($) (s mp) (n - 1) which evaluates to s mp (n - 1) The parsing goes this way because ($) has the lowers precedence. -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From sbarak.sb at gmail.com Tue Jun 9 01:56:46 2015 From: sbarak.sb at gmail.com (steve barak) Date: Mon, 8 Jun 2015 18:56:46 -0700 Subject: [Haskell-beginners] (no subject) Message-ID: Unsuscribe me from this list Steve Barak -------------- next part -------------- An HTML attachment was scrubbed... URL: From sumit.sahrawat.apm13 at iitbhu.ac.in Tue Jun 9 01:57:19 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Tue, 9 Jun 2015 07:27:19 +0530 Subject: [Haskell-beginners] cabal install glfw failing In-Reply-To: <55758B2B.80303@vlkk.cz> References: <55758B2B.80303@vlkk.cz> Message-ID: It seems like the gflw package doesn't support ghc 7.10 yet. Try downgrading to 7.8.4 and it should work. On 8 June 2015 at 18:01, Martin Vlk wrote: > Hi, I am trying to install the Euterpea library, which depends on glfw, > but it is failing to install with a compilation failure. > > Could someone take a look at the error and tell me what might be wrong? > > Many Thanks > Martin > > The Glorious Glasgow Haskell Compilation System, version 7.10.1 > cabal-install version 1.22.4.0 > using version 1.22.3.0 of the Cabal library > > $ cabal update > $ cabal install glfw > > Resolving dependencies... > Configuring GLFW-0.5.2.2... > Failed to install GLFW-0.5.2.2 > Build log ( /home/martin/.cabal/logs/GLFW-0.5.2.2.log ): > cabal: Error: some packages failed to install: > GLFW-0.5.2.2 failed during the configure step. The exception was: > user error ('/home/martin/.ghc/bin/ghc' exited with an error: > > /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:106:14: > No instance for (Applicative (StateT ConfState IO)) > arising from a use of ?modify? > In the expression: modify > In the expression: > modify $ \ (ConfState fs ls) -> ConfState fs (lib : ls) > In an equation for ?addLib?: > addLib lib > = modify $ \ (ConfState fs ls) -> ConfState fs (lib : ls) > > /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:242:10: > Could not deduce (Applicative (StateT s m)) > arising from the superclasses of an instance declaration > from the context (Monad m) > bound by the instance declaration > at /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:242:10-40 > In the instance declaration for ?Monad (StateT s m)? > > /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:252:10: > Could not deduce (Applicative (StateT s m)) > arising from the superclasses of an instance declaration > from the context (Monad m) > bound by the instance declaration > at /tmp/GLFW-0.5.2.2-20349/GLFW-0.5.2.2/dist/setup/setup.hs:252:10-47 > In the instance declaration for ?MonadState s (StateT s m)? > ) > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From sumit.sahrawat.apm13 at iitbhu.ac.in Tue Jun 9 01:58:18 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Tue, 9 Jun 2015 07:28:18 +0530 Subject: [Haskell-beginners] (no subject) In-Reply-To: References: Message-ID: http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners On 9 June 2015 at 07:26, steve barak wrote: > Unsuscribe me from this list > > Steve Barak > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From sourabh.s.joshi at gmail.com Tue Jun 9 03:54:38 2015 From: sourabh.s.joshi at gmail.com (Sourabh) Date: Mon, 8 Jun 2015 20:54:38 -0700 Subject: [Haskell-beginners] Dynamic programming (memoization) w/ string keys. Message-ID: I haven't tried in another language yet. I wasn't aware of nim-sum, and looked up the game of nim. And yes, this sounds like a tweak on the nim problem, so I will take a look at game theory. Thank you for the pointers. Coursera has a course on combinatorial game theory, and I've put it on my watch list now! I'll try to tweak my program to use bits instead of strings. I don't think I've ever used bit shifting in Haskell (I've used it plenty in C), so it should be interesting. Thanks for the suggestions Stefan! > Do you have a dynamic programming solution which runs reasonably fast > in another language? Because this game of kyles looks like an example > from combinatoric game theory to me and as such it might be much more > efficient to solve it using nim-sums (if possible; I haven't given this > too much thought). > > Also note that, since your strings only consist of X and I, you could > also use Integers and bit-operations instead of lists in your > algorithms. You'd still need a Map for memoization, but other operations > might be much faster. > > Cheers -------------- next part -------------- An HTML attachment was scrubbed... URL: From defigueiredo at ucdavis.edu Tue Jun 9 04:04:15 2015 From: defigueiredo at ucdavis.edu (Dimitri DeFigueiredo) Date: Mon, 08 Jun 2015 22:04:15 -0600 Subject: [Haskell-beginners] grouping functions together In-Reply-To: References: <55760D54.2030101@ucdavis.edu> Message-ID: <557665BF.6070403@ucdavis.edu> I used typeclasses because I want to have a "default version" of the run function. I want that function to be able to call (specialized versions) of the other functions in the group. This is the only way *I know* to "factor out" common code in Haskell while still allowing the "factored out" code to call specialized versions of the other functions. In my view, this is very similar to inheritance and specialization is Object-Oriented Programming. Is there another way to do this? I don't see how I could do this with a record. If the run function were mostly the same for all types except for calls to specialized versions of the others. I think I would have to write a completely separate version of run for each instance. The example below shows what I mean. Also, my apologies, but my code was wrong. I now realize it did not capture what I need. I don't need the functions to be polymorphic for all types within a single instance. Within a single instance, I just need them to work for a few specific types. So, here's a better version (my current one): {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} import Control.Monad class Reliable m s where type Req s :: * -- the type for requests type Atp s :: * -- the type for attempts type Ack s :: * -- the type for acknowledgments type Res s :: * -- the type for results (Success) type Fai s :: * -- the type for failures getRequests :: Monad m => s -> m [Req s] mkAttempt :: Monad m => s -> Req s -> m (Maybe (Atp s)) action :: Monad m => s -> Atp s -> m (Maybe (Ack s)) getAcks :: Monad m => s ->[Atp s] -> m [Ack s] mkResult :: Monad m => s -> Req s -> Ack s -> m (Either (Fai s) (Res s)) run :: Monad m => s -> Req s -> m (Res s) data RemoteCall = RemoteCall instance Reliable IO RemoteCall where type Req RemoteCall = Int type Atp RemoteCall = String type Ack RemoteCall = Bool type Res RemoteCall = String type Fai RemoteCall = Int getRequests = undefined -- these can be specialized for each instance mkAttempt = undefined action = undefined getAcks = undefined mkResult = undefined run s req = do -- dummy version mAtp <- mkAttempt s req mAck <- action s (fromJust mAtp) eRes <- mkResult s req (fromJust mAck) return $ case eRes of Left f -> error "failure" Right s -> s I don't know how I would write the 'run' function above only once if I were using records. It seems I would have to duplicate code, no? Thank you! Dimitri On 08/06/15 16:36, Rein Henrichs wrote: > This seems like a case where you only really need a record, not a > typeclass. > > On Mon, Jun 8, 2015 at 2:47 PM Dimitri DeFigueiredo > > wrote: > > Hello! > > I am trying to tie together a group of functions that turn an > unreliable > remote network call into a reliable one. For each different network > request I make, a specific group of these functions should always work > together, but their type signatures are quite different. My first > thought was to put them all in a typeclass: > > import Control.Monad > > class Reliable1 m req attempt ack failure result where > getRequests1 :: Monad m => m [req] > mkAttempt1 :: Monad m => req -> m (Maybe attempt) > action1 :: Monad m => attempt -> m (Maybe ack) > getAcks1 :: Monad m => [attempt] -> m [ack] > mkResult1 :: Monad m => req -> ack -> m (Either failure > result) > run1 :: Monad m => req -> m result > > That doesn't work because not all functions use all parameters. For > example, getAcks1 has no idea of what the final 'result' type > parameter > is. This lead me to my second attempt. Defining a 'service' type with > the sole purpose of tying them all together. Here's my current > attempt: > > {-# LANGUAGE MultiParamTypeClasses #-} > > import Control.Monad > > class Reliable m service where > getReqs :: Monad m => service -> m [req] > mkAttempt :: Monad m => service -> req -> m (Maybe attempt) > action :: Monad m => service -> attempt -> m (Maybe ack) > getAcks :: Monad m => service -> [attempt] -> m [ack] > mkResult :: Monad m => service -> req -> ack -> m (Either > failure result) > run :: Monad m => service -> req -> m result > > data RemoteCall = RemoteCall > > instance Reliable IO RemoteCall where > getReqs = undefined > mkAttempt = undefined > action = undefined > getAcks = undefined > mkResult = undefined > run = undefined > > This works, but I have to explicitly pass the 'service' argument in > every call. > Can I avoid passing this parameter every time? > Question, is there a better way to do this? > I wanted to have a wrapper to make my remote calls reliable. > > Thanks, > > Dimitri > > > > _______________________________________________ > 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 4bea6c869366227b879ffe4abad50c at gmail.com Tue Jun 9 06:45:06 2015 From: 4bea6c869366227b879ffe4abad50c at gmail.com (Csaba Marosi) Date: Tue, 9 Jun 2015 06:45:06 +0000 Subject: [Haskell-beginners] parallel map/filter In-Reply-To: References: Message-ID: Thanks for the tips, some comments: a) I tried to print the list before my expensive map (prints fast) and even copy-paste the content into the source code, but it did not help. b) What do you mean by this? One more question: when I run my program with -s, the stats: 4,961,037,352 bytes allocated in the heap 19,431,024 bytes copied during GC [...] 3 MB total memory in use (0 MB lost due to fragmentation) What does the first number (~ 5G memory) mean? When I wrote my functions, I just assumed that even the bad code will be fast enough. (Even this question is more about learning that a practical issue.) Can you recommend any docs about this kind of Haskell internals? PS: splitting the input file to two, and use bash to wait both half reduces the runtime by ~40%. What I want here is to annotate my program with this knowledge to help ghc to beat bash :) On 6/5/15, Marcin Mrotek wrote: > My first guesses would be that: > a) Your program is slowed down because lines from the file is read one line > by one, i.e. there's lazy IO at work. Have you tried your code on a list > that's loaded in the memory as a whole at once? > b) The cost of dereferencing the next link in a list overwhelms the cost of > computing one answer. Have you tried using a tree instead? > > Best regards, > Marcin Mrotek > From vale.cofershabica at gmail.com Tue Jun 9 15:25:43 2015 From: vale.cofershabica at gmail.com (Vale Cofer-Shabica) Date: Tue, 9 Jun 2015 11:25:43 -0400 Subject: [Haskell-beginners] Proper use of exit{Success,Failure} Message-ID: Dear all, I'm writing a command line program which may need to exit early based on some condition. Because of the pipeline the program is a part of, I want to be able to control the exit status when it does terminate. I can successfully use 'error' to indicate failure, but also want to exit early with success (or any other status). Here's what I've managed: >import System.Exit (exitSuccess) >import Control.Monad (when) >main = do ... code to reasonably initialize condition, e.g.: > let condition = True > when condition (putStrLn "Bailing out.")>>exitSuccess>>(return ()) ... program continues If I remove ">>(return ())" my code will not typecheck because "exitSuccess :: IO a". But this looks ugly and smells sufficiently like a kludge that I presume there is a better way to do it. Any suggestions appreciated, vale From sumit.sahrawat.apm13 at iitbhu.ac.in Tue Jun 9 15:27:52 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Tue, 9 Jun 2015 20:57:52 +0530 Subject: [Haskell-beginners] Proper use of exit{Success,Failure} In-Reply-To: References: Message-ID: Try `Control.Monad.void`. It is equivalent of adding `>> return ()` to the end of a block. void $ do ... On 9 June 2015 at 20:55, Vale Cofer-Shabica wrote: > Dear all, > > I'm writing a command line program which may need to exit early based > on some condition. Because of the pipeline the program is a part of, I > want to be able to control the exit status when it does terminate. I > can successfully use 'error' to indicate failure, but also want to > exit early with success (or any other status). Here's what I've > managed: > > >import System.Exit (exitSuccess) > >import Control.Monad (when) > > >main = do > > ... code to reasonably initialize condition, e.g.: > > > let condition = True > > when condition (putStrLn "Bailing out.")>>exitSuccess>>(return ()) > > ... program continues > > If I remove ">>(return ())" my code will not typecheck because > "exitSuccess :: IO a". But this looks ugly and smells sufficiently > like a kludge that I presume there is a better way to do it. > > Any suggestions appreciated, > vale > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From ahammel87 at gmail.com Tue Jun 9 15:38:15 2015 From: ahammel87 at gmail.com (Alex Hammel) Date: Tue, 09 Jun 2015 15:38:15 +0000 Subject: [Haskell-beginners] Proper use of exit{Success,Failure} In-Reply-To: References: Message-ID: exitSuccess :: IO a means that exitSuccess type-checks for any `a`. Your program should typecheck without `void`. I suspect you've got a stray paren. This prints "Bailing out." and exits zero for me: module Main where import System.Exit (exitSuccess) import Control.Monad (when) main = do let condition = True when condition (putStrLn "Bailing out." >> exitSuccess) putStrLn "Continuing normally..." On Tue, 9 Jun 2015 at 08:27 Sumit Sahrawat, Maths & Computing, IIT (BHU) < sumit.sahrawat.apm13 at iitbhu.ac.in> wrote: > Try `Control.Monad.void`. It is equivalent of adding `>> return ()` to the > end of a block. > > void $ do > ... > > On 9 June 2015 at 20:55, Vale Cofer-Shabica > wrote: > >> Dear all, >> >> I'm writing a command line program which may need to exit early based >> on some condition. Because of the pipeline the program is a part of, I >> want to be able to control the exit status when it does terminate. I >> can successfully use 'error' to indicate failure, but also want to >> exit early with success (or any other status). Here's what I've >> managed: >> >> >import System.Exit (exitSuccess) >> >import Control.Monad (when) >> >> >main = do >> >> ... code to reasonably initialize condition, e.g.: >> >> > let condition = True >> > when condition (putStrLn "Bailing out.")>>exitSuccess>>(return ()) >> >> ... program continues >> >> If I remove ">>(return ())" my code will not typecheck because >> "exitSuccess :: IO a". But this looks ugly and smells sufficiently >> like a kludge that I presume there is a better way to do it. >> >> Any suggestions appreciated, >> vale >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > > > > -- > Regards > > Sumit Sahrawat > _______________________________________________ > 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 vale.cofershabica at gmail.com Tue Jun 9 16:19:40 2015 From: vale.cofershabica at gmail.com (Vale Cofer-Shabica) Date: Tue, 9 Jun 2015 12:19:40 -0400 Subject: [Haskell-beginners] Proper use of exit{Success,Failure} In-Reply-To: References: Message-ID: Thank you Alex, Sumit! I did indeed have stray parentheses. I feel a bit silly for convincing myself that something with my types was wrong when it was just an error in grouping. Thanks for the clarification and the note about void. -vale On Tue, Jun 9, 2015 at 11:38 AM, Alex Hammel wrote: > exitSuccess :: IO a means that exitSuccess type-checks for any `a`. Your > program should typecheck without `void`. I suspect you've got a stray paren. > > This prints "Bailing out." and exits zero for me: > > module Main where > > import System.Exit (exitSuccess) > import Control.Monad (when) > > main = do > let condition = True > when condition (putStrLn "Bailing out." >> exitSuccess) > putStrLn "Continuing normally..." > > > On Tue, 9 Jun 2015 at 08:27 Sumit Sahrawat, Maths & Computing, IIT (BHU) > wrote: >> >> Try `Control.Monad.void`. It is equivalent of adding `>> return ()` to the >> end of a block. >> >> void $ do >> ... >> >> On 9 June 2015 at 20:55, Vale Cofer-Shabica >> wrote: >>> >>> Dear all, >>> >>> I'm writing a command line program which may need to exit early based >>> on some condition. Because of the pipeline the program is a part of, I >>> want to be able to control the exit status when it does terminate. I >>> can successfully use 'error' to indicate failure, but also want to >>> exit early with success (or any other status). Here's what I've >>> managed: >>> >>> >import System.Exit (exitSuccess) >>> >import Control.Monad (when) >>> >>> >main = do >>> >>> ... code to reasonably initialize condition, e.g.: >>> >>> > let condition = True >>> > when condition (putStrLn "Bailing out.")>>exitSuccess>>(return ()) >>> >>> ... program continues >>> >>> If I remove ">>(return ())" my code will not typecheck because >>> "exitSuccess :: IO a". But this looks ugly and smells sufficiently >>> like a kludge that I presume there is a better way to do it. >>> >>> Any suggestions appreciated, >>> vale >>> _______________________________________________ >>> Beginners mailing list >>> Beginners at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> >> >> >> -- >> Regards >> >> Sumit Sahrawat >> _______________________________________________ >> 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 mike_k_houghton at yahoo.co.uk Wed Jun 10 16:35:05 2015 From: mike_k_houghton at yahoo.co.uk (Mike Houghton) Date: Wed, 10 Jun 2015 17:35:05 +0100 Subject: [Haskell-beginners] 'Simple' function Message-ID: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> Hi, I?ve been tryimg to write a function with signature asString :: IO String -> String Does someone please have the patience to explain to me what the compiler error messages really mean for these two attempts and exactly what I?m doing (!!!) If I *do not* give this function any type signature then it works i.e.. asString ioStr = do str <- ioStr return $ str and the compiler tells me its signature is asString :: forall (m :: * -> *) b. Monad m => m b -> m b which, at this stage of my Haskell progress, is just pure Voodoo. Why isn?t it?s signature asString :: IO String -> String ? Another naive attempt is asString ioStr = str where str <- ioStr and then compiler says parse error on input ?<-? Many Thanks Mike From theblessedadventhope at gmail.com Wed Jun 10 16:47:54 2015 From: theblessedadventhope at gmail.com (Steven Williams) Date: Wed, 10 Jun 2015 12:47:54 -0400 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> Message-ID: <55786A3A.7000209@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Here is return's type signature: return :: Monad m => a -> m a What you are doing with the do notation can also be expressed as ioStr >> = (\str -> return str). do notation and bind both require you to have a value that has the same monad as before. Steven Williams My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA On 10/06/15 12:35, Mike Houghton wrote: > Hi, > > I?ve been tryimg to write a function with signature > > asString :: IO String -> String > > > Does someone please have the patience to explain to me what the > compiler error messages really mean for these two attempts and > exactly what I?m doing (!!!) If I *do not* give this function any > type signature then it works i.e.. > > asString ioStr = do str <- ioStr return $ str > > and the compiler tells me its signature is > > asString :: forall (m :: * -> *) b. Monad m => m b -> m b > > which, at this stage of my Haskell progress, is just pure Voodoo. > Why isn?t it?s signature asString :: IO String -> String ? > > > Another naive attempt is asString ioStr = str where str <- ioStr > > and then compiler says parse error on input ?<-? > > > Many Thanks > > Mike > > _______________________________________________ Beginners mailing > list Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 +RlHcYv+qp4J8nI59pFW =Vunc -----END PGP SIGNATURE----- From allbery.b at gmail.com Wed Jun 10 17:06:07 2015 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 10 Jun 2015 13:06:07 -0400 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> Message-ID: On Wed, Jun 10, 2015 at 12:35 PM, Mike Houghton wrote: > asString ioStr = do > str <- ioStr > return $ str > > and the compiler tells me its signature is > > asString :: forall (m :: * -> *) b. Monad m => m b -> m b > > which, at this stage of my Haskell progress, is just pure Voodoo. > Why isn?t it?s signature asString :: IO String -> String ? > Because the only thing it knows about ioStr is that it is a monadic action. IO is not the only monad, nor even the only useful monad. And "do" syntax including <- is not specific to IO. That said, most of the type signature it showed you is only important if you are doing advanced things like type level programming. The short version of that type signature is asString :: Monad m -> m b -> m b asString ioStr = str where > str <- ioStr > > and then compiler says > parse error on input ?<-? > <- is part of "do" syntax, it cannot be used by itself like that. Just to give you some idea of what's really going on, let me show you that first one without the "do" syntax: asString ioStr = ioStr >>= (\s -> return $ s) (Let me additionally note that the "$" does nothing whatsoever in either case, and can and should be left out. Moreover, (x >>= \y -> return y) is just a long-winded way of writing (x).) -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From aldiyen at aldiyen.com Wed Jun 10 17:08:43 2015 From: aldiyen at aldiyen.com (aldiyen) Date: Wed, 10 Jun 2015 13:08:43 -0400 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <55786A3A.7000209@gmail.com> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> Message-ID: And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO -aldiyen > On Jun 10, 2015, at 12:47, Steven Williams wrote: > > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Here is return's type signature: > > return :: Monad m => a -> m a > > What you are doing with the do notation can also be expressed as ioStr >>> = (\str -> return str). > > do notation and bind both require you to have a value that has the > same monad as before. > > Steven Williams > My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 > FA > >> On 10/06/15 12:35, Mike Houghton wrote: >> Hi, >> >> I?ve been tryimg to write a function with signature >> >> asString :: IO String -> String >> >> >> Does someone please have the patience to explain to me what the >> compiler error messages really mean for these two attempts and >> exactly what I?m doing (!!!) If I *do not* give this function any >> type signature then it works i.e.. >> >> asString ioStr = do str <- ioStr return $ str >> >> and the compiler tells me its signature is >> >> asString :: forall (m :: * -> *) b. Monad m => m b -> m b >> >> which, at this stage of my Haskell progress, is just pure Voodoo. >> Why isn?t it?s signature asString :: IO String -> String ? >> >> >> Another naive attempt is asString ioStr = str where str <- ioStr >> >> and then compiler says parse error on input ?<-? >> >> >> Many Thanks >> >> Mike >> >> _______________________________________________ Beginners mailing >> list Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v2 > > iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt > JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc > HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl > 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 > emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg > e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s > ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL > 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE > m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL > xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc > K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 > +RlHcYv+qp4J8nI59pFW > =Vunc > -----END PGP SIGNATURE----- > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From allbery.b at gmail.com Wed Jun 10 17:16:39 2015 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 10 Jun 2015 13:16:39 -0400 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> Message-ID: On Wed, Jun 10, 2015 at 1:06 PM, Brandon Allbery wrote: > asString :: Monad m -> m b -> m b Typoed, sigh.... asString :: Monad m => m b -> m b The thing before the => is a "constraint", in this specifying that the type "m" must be a type for which an instance of the Monad typeclass has been defined. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From imantc at gmail.com Wed Jun 10 17:20:10 2015 From: imantc at gmail.com (Imants Cekusins) Date: Wed, 10 Jun 2015 19:20:10 +0200 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> Message-ID: Mike, if you are trying to run a "hello world" program in ghci, here are 2 working functions. -- #1 : all it does is prompts for input and sends the value back to IO module Text where ioStr :: IO() ioStr = do putStrLn "enter anything" str <- getLine putStrLn str -- #2 this program prepends the string you pass to it as an arg with "Hello" str2str:: String -> String str2str s = "Hello " ++ s -- how to run: -- #1 : ioStr -- #2 : str2str "some text" hope this helps On 10 June 2015 at 19:08, aldiyen wrote: > And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO > > -aldiyen > > > >> On Jun 10, 2015, at 12:47, Steven Williams wrote: >> >> -----BEGIN PGP SIGNED MESSAGE----- >> Hash: SHA1 >> >> Here is return's type signature: >> >> return :: Monad m => a -> m a >> >> What you are doing with the do notation can also be expressed as ioStr >>>> = (\str -> return str). >> >> do notation and bind both require you to have a value that has the >> same monad as before. >> >> Steven Williams >> My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 >> FA >> >>> On 10/06/15 12:35, Mike Houghton wrote: >>> Hi, >>> >>> I?ve been tryimg to write a function with signature >>> >>> asString :: IO String -> String >>> >>> >>> Does someone please have the patience to explain to me what the >>> compiler error messages really mean for these two attempts and >>> exactly what I?m doing (!!!) If I *do not* give this function any >>> type signature then it works i.e.. >>> >>> asString ioStr = do str <- ioStr return $ str >>> >>> and the compiler tells me its signature is >>> >>> asString :: forall (m :: * -> *) b. Monad m => m b -> m b >>> >>> which, at this stage of my Haskell progress, is just pure Voodoo. >>> Why isn?t it?s signature asString :: IO String -> String ? >>> >>> >>> Another naive attempt is asString ioStr = str where str <- ioStr >>> >>> and then compiler says parse error on input ?<-? >>> >>> >>> Many Thanks >>> >>> Mike >>> >>> _______________________________________________ Beginners mailing >>> list Beginners at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> -----BEGIN PGP SIGNATURE----- >> Version: GnuPG v2 >> >> iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt >> JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc >> HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl >> 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 >> emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg >> e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s >> ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL >> 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE >> m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL >> xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc >> K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 >> +RlHcYv+qp4J8nI59pFW >> =Vunc >> -----END PGP SIGNATURE----- >> _______________________________________________ >> 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 mike_k_houghton at yahoo.co.uk Wed Jun 10 17:50:04 2015 From: mike_k_houghton at yahoo.co.uk (Mike Houghton) Date: Wed, 10 Jun 2015 18:50:04 +0100 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> Message-ID: <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Thanks for all the replies! It?s become a little clearer. However? (again this is naive begginer stuff.. ) if the signature is asString :: IO String -> String why is this not a pure function? The IO string has already been supplied - maybe via keyboard input - and so for the same IO String the function will always return the same value. Surely this behaviour is different to a monadic function that reads the keyboard and its output (rather than the input) could be different. ie if I give asString an input of IO ?myString? then it will always return ?myString? every time I invoke it with IO ?myString? Many thanks Mike > On 10 Jun 2015, at 18:20, Imants Cekusins wrote: > > Mike, if you are trying to run a "hello world" program in ghci, here > are 2 working functions. > > -- #1 : all it does is prompts for input and sends the value back to IO > > module Text where > > ioStr :: IO() > ioStr = do > putStrLn "enter anything" > str <- getLine > putStrLn str > > > -- #2 this program prepends the string you pass to it as an arg with "Hello" > > str2str:: String -> String > str2str s = "Hello " ++ s > > > -- how to run: > -- #1 : ioStr > -- #2 : str2str "some text" > > hope this helps > > > On 10 June 2015 at 19:08, aldiyen wrote: >> And just as a note, you can't really ever get the value inside the IO monad out. IO is not pure / non-deterministic, since it depends on something outside the program, and there's no way to "make it pure", as it were. You have to do all your operations on that String within the context of an IO >> >> -aldiyen >> >> >> >>> On Jun 10, 2015, at 12:47, Steven Williams wrote: >>> >>> -----BEGIN PGP SIGNED MESSAGE----- >>> Hash: SHA1 >>> >>> Here is return's type signature: >>> >>> return :: Monad m => a -> m a >>> >>> What you are doing with the do notation can also be expressed as ioStr >>>>> = (\str -> return str). >>> >>> do notation and bind both require you to have a value that has the >>> same monad as before. >>> >>> Steven Williams >>> My PGP Key: http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 >>> FA >>> >>>> On 10/06/15 12:35, Mike Houghton wrote: >>>> Hi, >>>> >>>> I?ve been tryimg to write a function with signature >>>> >>>> asString :: IO String -> String >>>> >>>> >>>> Does someone please have the patience to explain to me what the >>>> compiler error messages really mean for these two attempts and >>>> exactly what I?m doing (!!!) If I *do not* give this function any >>>> type signature then it works i.e.. >>>> >>>> asString ioStr = do str <- ioStr return $ str >>>> >>>> and the compiler tells me its signature is >>>> >>>> asString :: forall (m :: * -> *) b. Monad m => m b -> m b >>>> >>>> which, at this stage of my Haskell progress, is just pure Voodoo. >>>> Why isn?t it?s signature asString :: IO String -> String ? >>>> >>>> >>>> Another naive attempt is asString ioStr = str where str <- ioStr >>>> >>>> and then compiler says parse error on input ?<-? >>>> >>>> >>>> Many Thanks >>>> >>>> Mike >>>> >>>> _______________________________________________ Beginners mailing >>>> list Beginners at haskell.org >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >>> -----BEGIN PGP SIGNATURE----- >>> Version: GnuPG v2 >>> >>> iQIcBAEBAgAGBQJVeGo5AAoJEMrKbHRmmlT6N8UP/i/tAhDtyHiG3sgH3e5xAqyt >>> JAsyX2JaBQVjERRVaJQy1+Pg9hNdGBCrVljxY0BH5B8np956bnuIEyZKtSc2i2Jc >>> HM0lBesyzCYqw29QxAyFFno07iXQllocZaHUIgC4AoNYO5zNGSPYcNaB4O5SYoKl >>> 83Cjz97BHgAHkvHpsLDLOpizOkP+CsXwi8s/KRKoidLkbQpmv9SpqiFvmm9u+UK1 >>> emZF/4veFE4Ay3AvIsxMpn7M5hVoKgat1xyGX02IrenvkOL69IIYc+4OvzK49Lxg >>> e8jrAehJDMh+U7zN+qVCY1ZyJbJF+uGawFC+XoswOdAra+Q23te77RKkligkmN7s >>> ACut72hwTejZN/sIaORqZXuy+HUY1LjlJnlz0RCdG1CLkr3EaKG5ZCX3E2N8RnxL >>> 1CKtEdtFJGDeBcIBh5my/7IC22loTpVhBhPU2DPo+iOP2sRsUs0nllbqbjGfGpuE >>> m37dR/tfq9FKwqYS5RUuAcZ8fWuPdojmO2WvI4thHBGJhsRK4gqhAI4MnKLHBEoL >>> xfyHSaoFif/jC7peF/+ZPjKSsIpCJU+R/tDUBM9u22o3IVeTs1sWGZXM7J32tlGc >>> K/MTF/F3phcxwSCqb99WBHhXOIkKSgp47gx1INgDZFug/CgjUI1Sl4jvZ5j/45D5 >>> +RlHcYv+qp4J8nI59pFW >>> =Vunc >>> -----END PGP SIGNATURE----- >>> _______________________________________________ >>> 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 > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From marcin.jan.mrotek at gmail.com Wed Jun 10 18:15:41 2015 From: marcin.jan.mrotek at gmail.com (Marcin Mrotek) Date: Wed, 10 Jun 2015 20:15:41 +0200 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Message-ID: Hello, The key word here is "if I give asSting an input of IO "myString". Any function that returns and IO "myString" (this is really a misnomer, an (IO String) is a black box that stores the string obtained from an external source, but in an implementation-dependent, not-visible-to-an-user way) can do an arbitrary interaction with the real world to obtain the value. It can look at the keyborad input, read a file, connect to some networked resource, etc. That's why, this is not a pure function because every time you call it, it may return a different string. Or simply put, there's no legal way to write a function with that signature (okay, you can make it happen by using the unsafePerformIO function, but beware, it's called "unsafe" for a reason. It can cause a whole lot of seemingly "magic", unexpected behavior. In general, don't use it unless you really know it won't bite you) I don't know how to explain it more thoroughly. If you want to get deeper into Haskell, it could be said that ANY Haskell function or value is "pure" - for example an (IO String) value is always the same, well, (IO String) value, but the String "inside" may differ (just like a (Maybe String) or [String] is a wholly different beast than a mere String) If you want to connect pure functions to impure function do it the other way around - promote pure functions to IO (or any other monad). For example, you can use any pure function when using do notation easily. You can also compose any function of type (a -> b) with return to create a function (a -> m b). IO, being a monad, also implements many type classes from here: https://wiki.haskell.org/Typeclassopedia so you can turn a (a -> b) function into a (IO a -> IO b) function with just a fmap or <$>, for example. Best regards, Marcin Mrotek From yjuglaret at gmail.com Wed Jun 10 18:22:20 2015 From: yjuglaret at gmail.com (Yannis Juglaret) Date: Wed, 10 Jun 2015 20:22:20 +0200 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Message-ID: <5578805C.5050703@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Assuming asString :: IO String -> String we have getLine :: IO String asString getLine :: String Yet asString getLine could be "Hello" the first time you use it, then "Hi" the second time you use it. Same argument, different result, so this is not a pure function. - -- Yannis On 10/06/2015 19:50, Mike Houghton wrote: > Thanks for all the replies! It?s become a little clearer. However? > (again this is naive begginer stuff.. ) if the signature is > > asString :: IO String -> String > > why is this not a pure function? The IO string has already been > supplied - maybe via keyboard input - and so for the same IO String > the function will always return the same value. Surely this > behaviour is different to a monadic function that reads the > keyboard and its output (rather than the input) could be > different. ie if I give asString an input of IO ?myString? then > it will always return ?myString? every time I invoke it with IO > ?myString? > > Many thanks > > Mike > > > > >> On 10 Jun 2015, at 18:20, Imants Cekusins >> wrote: >> >> Mike, if you are trying to run a "hello world" program in ghci, >> here are 2 working functions. >> >> -- #1 : all it does is prompts for input and sends the value back >> to IO >> >> module Text where >> >> ioStr :: IO() ioStr = do putStrLn "enter anything" str <- >> getLine putStrLn str >> >> >> -- #2 this program prepends the string you pass to it as an arg >> with "Hello" >> >> str2str:: String -> String str2str s = "Hello " ++ s >> >> >> -- how to run: -- #1 : ioStr -- #2 : str2str "some text" >> >> hope this helps >> >> >> On 10 June 2015 at 19:08, aldiyen wrote: >>> And just as a note, you can't really ever get the value inside >>> the IO monad out. IO is not pure / non-deterministic, since it >>> depends on something outside the program, and there's no way to >>> "make it pure", as it were. You have to do all your operations >>> on that String within the context of an IO >>> >>> -aldiyen >>> >>> >>> >>>> On Jun 10, 2015, at 12:47, Steven Williams >>>> wrote: >>>> > Here is return's type signature: > > return :: Monad m => a -> m a > > What you are doing with the do notation can also be expressed as > ioStr >>>>>>> = (\str -> return str). > > do notation and bind both require you to have a value that has the > same monad as before. > > Steven Williams My PGP Key: > http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA > >>>>>> On 10/06/15 12:35, Mike Houghton wrote: Hi, >>>>>> >>>>>> I?ve been tryimg to write a function with signature >>>>>> >>>>>> asString :: IO String -> String >>>>>> >>>>>> >>>>>> Does someone please have the patience to explain to me >>>>>> what the compiler error messages really mean for these >>>>>> two attempts and exactly what I?m doing (!!!) If I *do >>>>>> not* give this function any type signature then it works >>>>>> i.e.. >>>>>> >>>>>> asString ioStr = do str <- ioStr return $ str >>>>>> >>>>>> and the compiler tells me its signature is >>>>>> >>>>>> asString :: forall (m :: * -> *) b. Monad m => m b -> m >>>>>> b >>>>>> >>>>>> which, at this stage of my Haskell progress, is just pure >>>>>> Voodoo. Why isn?t it?s signature asString :: IO String >>>>>> -> String ? >>>>>> >>>>>> >>>>>> Another naive attempt is asString ioStr = str where str >>>>>> <- ioStr >>>>>> >>>>>> and then compiler says parse error on input ?<-? >>>>>> >>>>>> >>>>>> Many Thanks >>>>>> >>>>>> Mike >>>>>> >>>>>> _______________________________________________ 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 >>> _______________________________________________ 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 > > _______________________________________________ Beginners mailing > list Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > - -- Yannis JUGLARET From rein.henrichs at gmail.com Wed Jun 10 18:46:32 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Wed, 10 Jun 2015 18:46:32 +0000 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Message-ID: On Wed, Jun 10, 2015 at 10:50 AM Mike Houghton wrote: > The IO string has already been supplied - maybe via keyboard input - > A value of type IO String has been provided, but a value of type IO String *is not a string.* In much the same way that `ls` is not a list of files, but rather a recipe for retrieving a list of files, a value of type IO String is a not a String but a recipe for performing IO that will retrieve a String once it is executed. It is important to remember is that *evaluating an IO action does not execute it*. Only the runtime system can do that, and the only IO action the runtime system executes is main (which can, of course, be composed of many other IO actions by using, e.g., the Monad interface). You can't write a function of type IO String -> String that "retrieves" the string because there is no string to retrieve. There is only a recipe that must be *executed* and that execution must stay within the IO context. (It is possible to write this function using unsafePerformIO precisely because unsafePerformIO instructs the runtime to ignore its usual safety mechanisms (that ensure that IO actions can be used with in a safe, pure, and referentially transparent way) and force the execution of the IO action as part of its evalulation and, as the name suggests, this is unsafe for a number of reasons and should only be used when the programmer is willing to take on the obligation to prove that they are using it in safe way.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From rein.henrichs at gmail.com Wed Jun 10 18:55:22 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Wed, 10 Jun 2015 18:55:22 +0000 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Message-ID: On Wed, Jun 10, 2015 at 11:15 AM Marcin Mrotek wrote: > That's why, this is not a pure function because every time you call it, it > may return a different string. > This is a common source of confusion. A value of type IO a for some a is not an impure function because it is not a function. Its *evaluation* is completely pure and referentially transparent: every time you evaluate `getLine`, you get the same IO String value. The only observable difference is under execution, but *we don't expect execution to be pure*: we only expect evaluation to be pure. -------------- next part -------------- An HTML attachment was scrubbed... URL: From yjuglaret at gmail.com Wed Jun 10 18:59:54 2015 From: yjuglaret at gmail.com (Yannis Juglaret) Date: Wed, 10 Jun 2015 20:59:54 +0200 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: <5578805C.5050703@gmail.com> References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> <5578805C.5050703@gmail.com> Message-ID: <5578892A.5040305@gmail.com> To be complete, my message actually assumes a function of that type *with the behavior you want*, which would be that of unsafePerformIO. Of course a trivial *pure* function with that type is for instance: asString _ = "Hi" But it does not have the behavior you want, it just ignores its argument. -- Yannis On 10/06/2015 20:22, Yannis Juglaret wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA256 > > Assuming > > asString :: IO String -> String > > we have > > getLine :: IO String > > asString getLine :: String > > Yet > > asString getLine > > could be "Hello" the first time you use it, then "Hi" the second time > you use it. Same argument, different result, so this is not a pure > function. > > - -- Yannis > > On 10/06/2015 19:50, Mike Houghton wrote: >> Thanks for all the replies! It?s become a little clearer. However? >> (again this is naive begginer stuff.. ) if the signature is >> >> asString :: IO String -> String >> >> why is this not a pure function? The IO string has already been >> supplied - maybe via keyboard input - and so for the same IO String >> the function will always return the same value. Surely this >> behaviour is different to a monadic function that reads the >> keyboard and its output (rather than the input) could be >> different. ie if I give asString an input of IO ?myString? then >> it will always return ?myString? every time I invoke it with IO >> ?myString? >> >> Many thanks >> >> Mike >> >> >> >> >>> On 10 Jun 2015, at 18:20, Imants Cekusins >>> wrote: >>> >>> Mike, if you are trying to run a "hello world" program in ghci, >>> here are 2 working functions. >>> >>> -- #1 : all it does is prompts for input and sends the value back >>> to IO >>> >>> module Text where >>> >>> ioStr :: IO() ioStr = do putStrLn "enter anything" str <- >>> getLine putStrLn str >>> >>> >>> -- #2 this program prepends the string you pass to it as an arg >>> with "Hello" >>> >>> str2str:: String -> String str2str s = "Hello " ++ s >>> >>> >>> -- how to run: -- #1 : ioStr -- #2 : str2str "some text" >>> >>> hope this helps >>> >>> >>> On 10 June 2015 at 19:08, aldiyen wrote: >>>> And just as a note, you can't really ever get the value inside >>>> the IO monad out. IO is not pure / non-deterministic, since it >>>> depends on something outside the program, and there's no way to >>>> "make it pure", as it were. You have to do all your operations >>>> on that String within the context of an IO >>>> >>>> -aldiyen >>>> >>>> >>>> >>>>> On Jun 10, 2015, at 12:47, Steven Williams >>>>> wrote: >>>>> >> Here is return's type signature: >> >> return :: Monad m => a -> m a >> >> What you are doing with the do notation can also be expressed as >> ioStr >>>>>>>> = (\str -> return str). >> >> do notation and bind both require you to have a value that has the >> same monad as before. >> >> Steven Williams My PGP Key: >> http://pgp.mit.edu/pks/lookup?op=get&search=0xCACA6C74669A54 FA >> >>>>>>> On 10/06/15 12:35, Mike Houghton wrote: Hi, >>>>>>> >>>>>>> I?ve been tryimg to write a function with signature >>>>>>> >>>>>>> asString :: IO String -> String >>>>>>> >>>>>>> >>>>>>> Does someone please have the patience to explain to me >>>>>>> what the compiler error messages really mean for these >>>>>>> two attempts and exactly what I?m doing (!!!) If I *do >>>>>>> not* give this function any type signature then it works >>>>>>> i.e.. >>>>>>> >>>>>>> asString ioStr = do str <- ioStr return $ str >>>>>>> >>>>>>> and the compiler tells me its signature is >>>>>>> >>>>>>> asString :: forall (m :: * -> *) b. Monad m => m b -> m >>>>>>> b >>>>>>> >>>>>>> which, at this stage of my Haskell progress, is just pure >>>>>>> Voodoo. Why isn?t it?s signature asString :: IO String >>>>>>> -> String ? >>>>>>> >>>>>>> >>>>>>> Another naive attempt is asString ioStr = str where str >>>>>>> <- ioStr >>>>>>> >>>>>>> and then compiler says parse error on input ?<-? >>>>>>> >>>>>>> >>>>>>> Many Thanks >>>>>>> >>>>>>> Mike >>>>>>> >>>>>>> _______________________________________________ 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 >>>> _______________________________________________ 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 >> >> _______________________________________________ Beginners mailing >> list Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > > - -- > Yannis JUGLARET > -- Yannis JUGLARET From marcin.jan.mrotek at gmail.com Wed Jun 10 19:00:17 2015 From: marcin.jan.mrotek at gmail.com (Marcin Mrotek) Date: Wed, 10 Jun 2015 21:00:17 +0200 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Message-ID: > This is a common source of confusion. A value of type IO a for some a is not > an impure function because it is not a function. Its evaluation is > completely pure and referentially transparent: every time you evaluate > `getLine`, you get the same IO String value. The only observable difference > is under execution, but we don't expect execution to be pure: we only expect > evaluation to be pure. Yeah, this is what I was trying to say in the latter part of my post, but I guess I ended up confusing the matter more :( Best regards, Marcin Mrotek From tkoster at gmail.com Thu Jun 11 05:53:41 2015 From: tkoster at gmail.com (Thomas Koster) Date: Thu, 11 Jun 2015 15:53:41 +1000 Subject: [Haskell-beginners] Escaping special characters in text Message-ID: Hi list, My program needs to escape and unescape "special characters" in text (Data.Text.Text), using my own definition of "special character" (isSpecial :: Char -> Bool). I am looking for a library that provides functions that implement or help me implement this functionality. I don't really care exactly how the special characters are escaped, but my preference is to prefix them with backslashes. While "attoparsec" does technically answer my question, it is as unimpressive an answer as "Prelude" unless the answer comes with a particularly clever and concise parser that blows my mind (and then kudos to the author). I am looking for a higher level library where I don't need to re-invent this wheel. That is, I don't want to write an unescaping parser if somebody has already published one on Hackage in a clean, well-tested library. My searches on Hoogle have turned up only network-uri, which offers percent-encoding with the definition of "special character" accepted as an argument [1]. This is the sort of thing I am after, although to use network-uri I would have to round-trip via String, something that I feel I should avoid. Functions of text types that return lazy text builders would be ideal. Also, percent-encoding is not my favourite encoding scheme. Thanks in advance. [1] https://hackage.haskell.org/package/network-uri/docs/Network-URI.html#v:escapeURIString -- Thomas Koster From efasckenoth at gmail.com Thu Jun 11 06:55:15 2015 From: efasckenoth at gmail.com (Stefan =?iso-8859-1?Q?H=F6ck?=) Date: Thu, 11 Jun 2015 08:55:15 +0200 Subject: [Haskell-beginners] Escaping special characters in text In-Reply-To: References: Message-ID: <20150611065515.GA1341@hunter.iway.ch> On Thu, Jun 11, 2015 at 03:53:41PM +1000, Thomas Koster wrote: > My program needs to escape and unescape "special characters" in text > (Data.Text.Text), using my own definition of "special character" > (isSpecial :: Char -> Bool). I am looking for a library that provides > functions that implement or help me implement this functionality. I > don't really care exactly how the special characters are escaped, but > my preference is to prefix them with backslashes. Hi Thomas The answer to your question depends on whether your program needs additional functionality. If the only thing you need to do is taking special characters and escaping them with an escape character plus a substitute character, this can be done with very little code using functions from Data.Text: import Data.Text (Text) import qualified Data.Text as T -- Character used for escaping ec :: Char ec = '$' -- Replace a character to be escaped with its substitute escapeChar :: Char -> Char escapeChar = id -- Inverse of escapeChar unescapeChar :: Char -> Char unescapeChar = id -- True if given char needs to be escaped isSpecial :: Char -> Bool isSpecial = ('?' ==) -- Escape chars in a given text escape :: Text -> Text escape = T.concatMap handleChar where handleChar c | isSpecial c = T.pack [ec, escapeChar c] | otherwise = T.singleton c -- Unescape chars in a given text unescape :: Text -> Text unescape t = case T.break (ec ==) t of (a,b) | T.null b -> a | otherwise -> let b' = T.tail b e = unescapeChar $ T.head b' in T.append a $ T.cons e $ unescape (T.tail b') This code was loaded into ghci and tested there, so it should compile (GHC 7.10). Example: escape $ T.pack "This?Is?A?Test??" yields "This$?Is$?A$?Test$?$?" 'unescape' yields the original string. Note that the implementation does not handle trailing escape characters: "This$?Is$?A$" will throw an exception, but this can be remedied with very little additional code. You of course must provide the correct implementation for 'ec', 'escapeChar', and 'unescapeChar'. These you need to implement no matter what other library you use. If on the other hand you want to escape special characters with blocks of text (instead of single characters as in my code) you probably also need a second character to mark the end of an escape. Even then, the code should not get much more involved than the example above. Text validation and error handling before unescaping adds some more bloat, but again should be straight forward to add using Either as a return type. So, either this is all you need, or we need more information. Cheers Stefan From mike_k_houghton at yahoo.co.uk Thu Jun 11 08:21:01 2015 From: mike_k_houghton at yahoo.co.uk (Mike Houghton) Date: Thu, 11 Jun 2015 09:21:01 +0100 Subject: [Haskell-beginners] Packages Message-ID: I?m using Cabal to build a package from some source I?m writing. It is not an executable but rather a library. How can I test locally that the package I?m making is complete? ie How do I reference the package I?ve just buiilt in a haskell source file? Thanks Mike From sumit.sahrawat.apm13 at iitbhu.ac.in Thu Jun 11 08:46:35 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Thu, 11 Jun 2015 14:16:35 +0530 Subject: [Haskell-beginners] Packages In-Reply-To: References: Message-ID: Your .cabal file will have some exported-modules. Install the library using `cabal install` and then import these modules to test them. Take a look here for more: https://www.haskell.org/cabal/users-guide/ On 11 June 2015 at 13:51, Mike Houghton wrote: > I?m using Cabal to build a package from some source I?m writing. It is > not an executable but rather a library. > How can I test locally that the package I?m making is complete? ie How do > I reference the package I?ve just buiilt in a haskell source file? > > > Thanks > Mike > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From mike_k_houghton at yahoo.co.uk Thu Jun 11 09:05:18 2015 From: mike_k_houghton at yahoo.co.uk (Mike Houghton) Date: Thu, 11 Jun 2015 10:05:18 +0100 Subject: [Haskell-beginners] Packages In-Reply-To: References: Message-ID: <65E8C48E-7D72-42D6-80EA-D95BFB3938CA@yahoo.co.uk> Thank you. > On 11 Jun 2015, at 09:46, Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote: > > Your .cabal file will have some exported-modules. Install the library using `cabal install` and then import these modules to test them. > > Take a look here for more: https://www.haskell.org/cabal/users-guide/ > > On 11 June 2015 at 13:51, Mike Houghton wrote: > I?m using Cabal to build a package from some source I?m writing. It is not an executable but rather a library. > How can I test locally that the package I?m making is complete? ie How do I reference the package I?ve just buiilt in a haskell source file? > > > Thanks > Mike > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > -- > Regards > > Sumit Sahrawat > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From tkoster at gmail.com Thu Jun 11 13:30:26 2015 From: tkoster at gmail.com (Thomas Koster) Date: Thu, 11 Jun 2015 23:30:26 +1000 Subject: [Haskell-beginners] Escaping special characters in text In-Reply-To: <20150611065515.GA1341@hunter.iway.ch> References: <20150611065515.GA1341@hunter.iway.ch> Message-ID: Stefan, On Thu, Jun 11, 2015 at 03:53:41PM +1000, Thomas Koster wrote: > My program needs to escape and unescape "special characters" in text > (Data.Text.Text), using my own definition of "special character" > (isSpecial :: Char -> Bool). I am looking for a library that provides > functions that implement or help me implement this functionality. I > don't really care exactly how the special characters are escaped, but > my preference is to prefix them with backslashes. On 11 June 2015 at 16:55, Stefan H?ck wrote: > The answer to your question depends on whether your program needs > additional functionality. If the only thing you need to do is taking > special characters and escaping them with an escape character plus a > substitute character, this can be done with very little code using > functions from Data.Text: > > import Data.Text (Text) > import qualified Data.Text as T > > -- Character used for escaping > ec :: Char > ec = '$' > > -- Replace a character to be escaped with its substitute > escapeChar :: Char -> Char > escapeChar = id > > -- Inverse of escapeChar > unescapeChar :: Char -> Char > unescapeChar = id > > -- True if given char needs to be escaped > isSpecial :: Char -> Bool > isSpecial = ('?' ==) > > -- Escape chars in a given text > escape :: Text -> Text > escape = T.concatMap handleChar > where handleChar c | isSpecial c = T.pack [ec, escapeChar c] > | otherwise = T.singleton c > > -- Unescape chars in a given text > unescape :: Text -> Text > unescape t = case T.break (ec ==) t of > (a,b) | T.null b -> a > | otherwise -> let b' = T.tail b > e = unescapeChar $ T.head b' > in T.append a $ > T.cons e $ unescape (T.tail b') Thank you for your response. Yes, this is all I need to do. I had completed about two thirds of a similar implementation before becoming concerned that I was spending too much time reinventing this particular wheel and that there may be much easier and/or shorter ways to do this using a library written by a wheel surgeon. The only substantial difference is that my own version uses and returns a Data.Text.Lazy.Builder so that texts can be streamed and spliced into larger texts without copying (I am also using Chris Done's formatting library [1]), but only if I get it right, of course, which is another reason why I started to look around for libraries by Haskellers more experienced than I. > If on the other hand you want to escape special characters with blocks of text > (instead of single characters as in my code) you probably also need a > second character to mark the end of an escape. Even then, the code > should not get much more involved than the example above. I don't need more functionality re the escaping itself; your implementation is a valid example that provides the essence of what I need. [1] https://hackage.haskell.org/package/formatting -- Thomas Koster From tkoster at gmail.com Fri Jun 12 04:11:21 2015 From: tkoster at gmail.com (Thomas Koster) Date: Fri, 12 Jun 2015 14:11:21 +1000 Subject: [Haskell-beginners] lens-aeson and error messages Message-ID: Hi list, tl;dr - I am using aeson and have an unusual JSON data structure to parse, so I have implemented the parseJSON function using the prisms and traversals in the lens-aeson package. Unfortunately, the only error message I ever get from my parser is "mempty". How can my parser give better error messages when using lens-aeson? Consider a need to implement parseJSON for the following type. data Row = Row [Text] Int Text The twist is that the values are in a JSON list, not an object. [["a","b","c"], 4, "a title"] The JSON above should be decoded to the following Haskell value. Row ["a", "b", "c"] 4 "a title" My first FromJSON instance was naive. instance FromJSON Row where parseJSON = withArray "Row" $ \ a -> case Vector.toList a of (x : y : z : []) -> Row <$> parseJSON x <*> parseJSON y <*> parseJSON z _ -> fail "Invalid Row." Then I decided that pattern matching a vector like that via an intermediate list was probably rookie stuff, so I tried lenses (this is my first attempt at lenses, btw). instance FromJSON Row where parseJSON v = Row <$> (v ^. nth 0 . to parseJSON) <*> (v ^. nth 1 . to parseJSON) <*> (v ^. nth 2 . to parseJSON) This looks like it works but now the only error message I get is "mempty". I think this is because the lens operators are folding with the Monoid Parser instance where mempty = fail "mempty". Can I continue to use lenses but produce better error messages? If so, how? The lens package haddocks baffle me. Any suggestions to improve my use of lenses are also welcome (e.g. the expression "to parseJSON" seems so useful that I thought it might be named in the lens-aeson package. But it isn't, so its absence makes me suspect that I'm using it incorrectly). Alternative, non-lens-based suggestions for de-constructing a Vector, pattern matching its elements, without too many intermediate lists or tuples are also welcome. Thanks in advance. -- Thomas Koster From mike_k_houghton at yahoo.co.uk Sat Jun 13 07:25:05 2015 From: mike_k_houghton at yahoo.co.uk (Mike Houghton) Date: Sat, 13 Jun 2015 08:25:05 +0100 Subject: [Haskell-beginners] Config data In-Reply-To: References: <9CF9E935-C382-4692-91E4-91BDDB8DDB03@yahoo.co.uk> <1460553189.8392786.1433617637485.JavaMail.yahoo@mail.yahoo.com> Message-ID: <3E0A44E2-C7F2-46B8-89CE-23E99D554ADE@yahoo.co.uk> Hi, My primary uses case was to set username/passord and server details for an emailing module. Using some of the ideas in this email chain I?ve written a small module at https://github.com/mike-k-houghton/AppConfig I hope someone might find it useful. Thanks > On 6 Jun 2015, at 21:14, Rein Henrichs wrote: > > Can we please not suggest "not recommended" solutions (that most of us probably wouldn't use) without at least providing a recommended alternative? > > You can parse the config file into a record and then either pass it as an argument wherever it is needed or use Reader (or ReaderT) to make it more implicit. > On Sat, Jun 6, 2015 at 12:16 PM Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote: > Yeah, sorry I missed the last line on my first read. > > The link I gave you also explains how to achieve the same functionality as global variables without using them. > The unsafePerformIO hack works, but for small modules it's much more helpful to do it safely. > > On 7 June 2015 at 00:37, mike h wrote: > Global state is an option - thanks. Didn't think Haskell allowed this. > > Having three modules may be more logical but doesn't it just put the same problem into the new module? > > Thanks > > > > On Saturday, 6 June 2015, 19:43, Mike Houghton wrote: > > > Hi, > > I?ve haskell files parser.hs and email.hs > email.hs is a module imported into parser and parser has the main. > > email has various passwords and server names needed to connect and send email. I want to have those details in a config file and read it in at start - using say config module. I?m ok with this part but the practicality of doing it eludes me... > > It seems to me that email module can either get the config details itself or be told them by parser. If email wants to get them how would it do this? It does not have a main that gets run so can?t load a config file.(can it ??) > > However parser can load the config in its main and then tell mail what the values are but how would mail save them? > > Of course I could chanage the signatures of the email send/receive functions in mail to take the connection details but that seems wrong. > > Thanks > > Mike > > > _______________________________________________ > 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 > > > > > -- > Regards > > Sumit Sahrawat > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From rasen.dubi at gmail.com Fri Jun 12 06:28:16 2015 From: rasen.dubi at gmail.com (Alexey Shmalko) Date: Fri, 12 Jun 2015 09:28:16 +0300 Subject: [Haskell-beginners] lens-aeson and error messages In-Reply-To: References: Message-ID: Hi, Thomas! I would come with implementation similar to this: instance FromJSON Row where parseJSON = withArray "Row" $ \ a -> case Vector.length a of 3 -> Row <$> parseJSON (a ! 0) <*> parseJSON (a ! 1) <*> parseJSON (a ! 2) _ -> fail "Invalid Row." Hope this helps. On Fri, Jun 12, 2015 at 7:11 AM, Thomas Koster wrote: > Hi list, > > tl;dr - I am using aeson and have an unusual JSON data structure to > parse, so I have implemented the parseJSON function using the prisms > and traversals in the lens-aeson package. Unfortunately, the only error > message I ever get from my parser is "mempty". How can my parser give > better error messages when using lens-aeson? > > Consider a need to implement parseJSON for the following type. > > data Row = Row [Text] Int Text > > The twist is that the values are in a JSON list, not an object. > > [["a","b","c"], 4, "a title"] > > The JSON above should be decoded to the following Haskell value. > > Row ["a", "b", "c"] 4 "a title" > > My first FromJSON instance was naive. > > instance FromJSON Row where > parseJSON = withArray "Row" $ \ a -> > case Vector.toList a of > (x : y : z : []) -> > Row <$> parseJSON x > <*> parseJSON y > <*> parseJSON z > _ -> fail "Invalid Row." > > Then I decided that pattern matching a vector like that via an > intermediate list was probably rookie stuff, so I tried lenses (this is > my first attempt at lenses, btw). > > instance FromJSON Row where > parseJSON v = > Row <$> (v ^. nth 0 . to parseJSON) > <*> (v ^. nth 1 . to parseJSON) > <*> (v ^. nth 2 . to parseJSON) > > This looks like it works but now the only error message I get is > "mempty". I think this is because the lens operators are folding with > the Monoid Parser instance where mempty = fail "mempty". > > Can I continue to use lenses but produce better error messages? If so, > how? The lens package haddocks baffle me. > > Any suggestions to improve my use of lenses are also welcome (e.g. the > expression "to parseJSON" seems so useful that I thought it might be > named in the lens-aeson package. But it isn't, so its absence makes me > suspect that I'm using it incorrectly). > > Alternative, non-lens-based suggestions for de-constructing a Vector, > pattern matching its elements, without too many intermediate lists or > tuples are also welcome. > > Thanks in advance. > > -- > Thomas Koster > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From karl at karlv.net Sat Jun 13 23:44:45 2015 From: karl at karlv.net (Karl Voelker) Date: Sat, 13 Jun 2015 16:44:45 -0700 Subject: [Haskell-beginners] Packages In-Reply-To: <65E8C48E-7D72-42D6-80EA-D95BFB3938CA@yahoo.co.uk> References: <65E8C48E-7D72-42D6-80EA-D95BFB3938CA@yahoo.co.uk> Message-ID: <1434239085.938021.294858897.0ABB1446@webmail.messagingengine.com> If your library has any internal modules, make sure to list them in the other-modules section of your cabal file. Every module has to be listed somewhere in the cabal file; otherwise, cabal will not include that module's source file in the tarball that can be built with the "cabal sdist" command. In other words, a more thorough test for package completeness is to run "cabal sdist," take the tarball somewhere else, extract it, and build from that. -Karl On Thu, Jun 11, 2015, at 02:05 AM, Mike Houghton wrote: > Thank you. > > > On 11 Jun 2015, at 09:46, Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote: > > > > Your .cabal file will have some exported-modules. Install the library using `cabal install` and then import these modules to test them. > > > > Take a look here for more: https://www.haskell.org/cabal/users-guide/ > > > > On 11 June 2015 at 13:51, Mike Houghton wrote: > > I?m using Cabal to build a package from some source I?m writing. It is not an executable but rather a library. > > How can I test locally that the package I?m making is complete? ie How do I reference the package I?ve just buiilt in a haskell source file? > > > > > > Thanks > > Mike > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > > > > > -- > > Regards > > > > Sumit Sahrawat > > _______________________________________________ > > 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 tkoster at gmail.com Sun Jun 14 09:11:32 2015 From: tkoster at gmail.com (Thomas Koster) Date: Sun, 14 Jun 2015 19:11:32 +1000 Subject: [Haskell-beginners] lens-aeson and error messages In-Reply-To: References: Message-ID: Hi Alexey, On Fri, Jun 12, 2015 at 7:11 AM, Thomas Koster wrote: > tl;dr - I am using aeson and have an unusual JSON data structure to > parse, so I have implemented the parseJSON function using the prisms > and traversals in the lens-aeson package. Unfortunately, the only error > message I ever get from my parser is "mempty". How can my parser give > better error messages when using lens-aeson? > > instance FromJSON Row where > parseJSON v = > Row <$> (v ^. nth 0 . to parseJSON) > <*> (v ^. nth 1 . to parseJSON) > <*> (v ^. nth 2 . to parseJSON) On 12 June 2015 at 16:28, Alexey Shmalko wrote: > I would come with implementation similar to this: > > instance FromJSON Row where > parseJSON = withArray "Row" $ \ a -> > case Vector.length a of > 3 -> > Row <$> parseJSON (a ! 0) > <*> parseJSON (a ! 1) > <*> parseJSON (a ! 2) > _ -> fail "Invalid Row." Thanks for your response. I was so caught up in trying to do things "the Haskell, functional way", with pattern matching, that I totally overlooked the plain old (!) operator! I have decided that Row is not complex enough to need lens-aeson and will follow your recommendation. I might add this (.!) operator to my toolkit though, analogous to (.:), to remove the need for those "parseJSON"s. (.!) :: FromJSON a => Array -> Int -> Parser a I wonder why this is missing from aeson... I am still interested if an answer to the original question exists, should I need lens-aeson at some later time. Thanks, -- Thomas Koster From driemer.riemer at gmail.com Sun Jun 14 22:09:16 2015 From: driemer.riemer at gmail.com (derek riemer) Date: Sun, 14 Jun 2015 16:09:16 -0600 Subject: [Haskell-beginners] splicing Message-ID: <557DFB8C.3070200@gmail.com> Hi guys, As a newby to haskell, I was curious, what is the best way to splice an array or do things in the middle? For example, binary search requires i do in sudocode define binary search array target. Find middle element. If target is middle element then return target else if target < middle element then binary search array[0:target] else binary search array[target:end] How can I get this splicing with haskell? I can't just use head here. I can't do array!!n: where n is some number. Thanks, Derek From driemer.riemer at gmail.com Sat Jun 13 13:36:28 2015 From: driemer.riemer at gmail.com (derek riemer) Date: Sat, 13 Jun 2015 07:36:28 -0600 Subject: [Haskell-beginners] splicing Message-ID: <557C31DC.9060705@gmail.com> Hi guys, As a newby to haskell, I was curious, what is the best way to splice an array or do things in the middle? For example, binary search requires i do in sudocode define binary search array target. Find middle element. If target is middle element then return target else if target < middle element then binary search array[0:target] else binary search array[target:end] How can I get this splicing with haskell? I can't just use head here. I can't do array!!n: where n is some number. Thanks, Derek From toad3k at gmail.com Mon Jun 15 02:35:04 2015 From: toad3k at gmail.com (David McBride) Date: Sun, 14 Jun 2015 22:35:04 -0400 Subject: [Haskell-beginners] splicing In-Reply-To: <557C31DC.9060705@gmail.com> References: <557C31DC.9060705@gmail.com> Message-ID: You can use the various splitAts in Data.List, Data.Vector to split a list at an index. You can also use drop and take to get a splice ie. drop 4 (take 2) is a splice from 3:5. On Sat, Jun 13, 2015 at 9:36 AM, derek riemer wrote: > Hi guys, > As a newby to haskell, I was curious, what is the best way to splice an > array or do things in the middle? > For example, binary search requires i do in sudocode > define binary search array target. > Find middle element. > If target is middle element then return target > else if target < middle element then > binary search array[0:target] > else > binary search array[target:end] > > How can I get this splicing with haskell? > I can't just use head here. > I can't do array!!n: where n is some number. > > Thanks, > Derek > _______________________________________________ > 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 shrvtsnvs at gmail.com Mon Jun 15 02:38:25 2015 From: shrvtsnvs at gmail.com (Shrivats) Date: Mon, 15 Jun 2015 08:08:25 +0530 Subject: [Haskell-beginners] splicing In-Reply-To: <557C31DC.9060705@gmail.com> References: <557C31DC.9060705@gmail.com> Message-ID: Hi, I don't see anything as a Prelude function, but you can do something with a combination of take and drop: rangeOf:: Int -> Int -> [a] rangeOf x y = take y . drop x rangeOf 2 4 [1 .. 5] -- [3,4,5] I have not included any bounds check. It's up to you. For added benefits, look up dropWhile and takeWhile. HTH. Hi guys, As a newby to haskell, I was curious, what is the best way to splice an array or do things in the middle? For example, binary search requires i do in sudocode define binary search array target. Find middle element. If target is middle element then return target else if target < middle element then binary search array[0:target] else binary search array[target:end] How can I get this splicing with haskell? I can't just use head here. I can't do array!!n: where n is some number. Thanks, Derek _______________________________________________ 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 michael at orlitzky.com Mon Jun 15 02:55:11 2015 From: michael at orlitzky.com (Michael Orlitzky) Date: Sun, 14 Jun 2015 22:55:11 -0400 Subject: [Haskell-beginners] splicing In-Reply-To: <557C31DC.9060705@gmail.com> References: <557C31DC.9060705@gmail.com> Message-ID: <557E3E8F.1080401@orlitzky.com> On 06/13/2015 09:36 AM, derek riemer wrote: > Hi guys, > As a newby to haskell, I was curious, what is the best way to splice an > array or do things in the middle? If you REALLY want to slice and aren't worried about index-safety, you should try using vectors instead of plain lists: https://hackage.haskell.org/package/vector/docs/Data-Vector.html On the right side of that page there's an index; you want the section called "Extracting subvectors (slicing)." You will need to install the "vector" package to get that stuff. From rasen.dubi at gmail.com Mon Jun 15 04:12:06 2015 From: rasen.dubi at gmail.com (Alexey Shmalko) Date: Mon, 15 Jun 2015 07:12:06 +0300 Subject: [Haskell-beginners] splicing In-Reply-To: <557DFB8C.3070200@gmail.com> References: <557DFB8C.3070200@gmail.com> Message-ID: Hi, Derek! Binary search algorithm requires random access, so you can't implement it (efficiently) using lists. You'd better try using something as vector [1]. It has both index and slice operations that work in O(1), so implementing binary search is a breeze. [1]: http://hackage.haskell.org/package/vector-0.10.12.3/docs/Data-Vector.html On Mon, Jun 15, 2015 at 1:09 AM, derek riemer wrote: > Hi guys, > As a newby to haskell, I was curious, what is the best way to splice an > array or do things in the middle? > For example, binary search requires i do in sudocode > define binary search array target. > Find middle element. > If target is middle element then return target > else if target < middle element then > binary search array[0:target] > else > binary search array[target:end] > > How can I get this splicing with haskell? > I can't just use head here. > I can't do array!!n: where n is some number. > > Thanks, > Derek > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From bob at redivi.com Mon Jun 15 04:16:06 2015 From: bob at redivi.com (Bob Ippolito) Date: Mon, 15 Jun 2015 06:16:06 +0200 Subject: [Haskell-beginners] splicing In-Reply-To: <557DFB8C.3070200@gmail.com> References: <557DFB8C.3070200@gmail.com> Message-ID: On Monday, June 15, 2015, derek riemer wrote: > Hi guys, > As a newby to haskell, I was curious, what is the best way to splice an > array or do things in the middle? > For example, binary search requires i do in sudocode > define binary search array target. > Find middle element. > If target is middle element then return target > else if target < middle element then > binary search array[0:target] > else > binary search array[target:end] > > How can I get this splicing with haskell? > I can't just use head here. > I can't do array!!n: where n is some number. You probably shouldn't use lists for binary search, since indexing a list is linear time. Binary searching a list is slower than a linear search. However, if you must, you can use splitAt for that purpose. Where you should really be looking for Array-like uses are Data.Vector or Data.Array. The former is probably better suited for this use case. You should also consider adding arguments to the search function for start and end indexes, rather than slicing the array itself. That's the more traditional way to implement it. -bob -------------- next part -------------- An HTML attachment was scrubbed... URL: From rasen.dubi at gmail.com Mon Jun 15 04:29:15 2015 From: rasen.dubi at gmail.com (Alexey Shmalko) Date: Mon, 15 Jun 2015 07:29:15 +0300 Subject: [Haskell-beginners] splicing In-Reply-To: References: <557DFB8C.3070200@gmail.com> Message-ID: Just a quick not that slicing vectors is O(1), it doesn't copy anything. I would prefer not passing start and end indexes and use slicing because: 1) You won't need a wrapper function 2) It's mentally easier to think in terms of halves ("ok, now do binary search in the right half") On Mon, Jun 15, 2015 at 7:16 AM, Bob Ippolito wrote: > On Monday, June 15, 2015, derek riemer wrote: >> >> Hi guys, >> As a newby to haskell, I was curious, what is the best way to splice an >> array or do things in the middle? >> For example, binary search requires i do in sudocode >> define binary search array target. >> Find middle element. >> If target is middle element then return target >> else if target < middle element then >> binary search array[0:target] >> else >> binary search array[target:end] >> >> How can I get this splicing with haskell? >> I can't just use head here. >> I can't do array!!n: where n is some number. > > > You probably shouldn't use lists for binary search, since indexing a list is > linear time. Binary searching a list is slower than a linear search. > However, if you must, you can use splitAt for that purpose. > > Where you should really be looking for Array-like uses are Data.Vector or > Data.Array. The former is probably better suited for this use case. > > You should also consider adding arguments to the search function for start > and end indexes, rather than slicing the array itself. That's the more > traditional way to implement it. > > -bob > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > From bob at redivi.com Mon Jun 15 05:05:30 2015 From: bob at redivi.com (Bob Ippolito) Date: Mon, 15 Jun 2015 07:05:30 +0200 Subject: [Haskell-beginners] splicing In-Reply-To: References: <557DFB8C.3070200@gmail.com> Message-ID: Which works ok (still a higher constant factor, O(1) isn't free) if you want a Bool or Maybe a answer, but if you want the index of the element you're searching for then slicing is not the best way. On Monday, June 15, 2015, Alexey Shmalko wrote: > Just a quick not that slicing vectors is O(1), it doesn't copy anything. > > I would prefer not passing start and end indexes and use slicing because: > 1) You won't need a wrapper function > 2) It's mentally easier to think in terms of halves ("ok, now do > binary search in the right half") > > On Mon, Jun 15, 2015 at 7:16 AM, Bob Ippolito > wrote: > > On Monday, June 15, 2015, derek riemer > wrote: > >> > >> Hi guys, > >> As a newby to haskell, I was curious, what is the best way to splice an > >> array or do things in the middle? > >> For example, binary search requires i do in sudocode > >> define binary search array target. > >> Find middle element. > >> If target is middle element then return target > >> else if target < middle element then > >> binary search array[0:target] > >> else > >> binary search array[target:end] > >> > >> How can I get this splicing with haskell? > >> I can't just use head here. > >> I can't do array!!n: where n is some number. > > > > > > You probably shouldn't use lists for binary search, since indexing a > list is > > linear time. Binary searching a list is slower than a linear search. > > However, if you must, you can use splitAt for that purpose. > > > > Where you should really be looking for Array-like uses are Data.Vector or > > Data.Array. The former is probably better suited for this use case. > > > > You should also consider adding arguments to the search function for > start > > and end indexes, rather than slicing the array itself. That's the more > > traditional way to implement it. > > > > -bob > > > > _______________________________________________ > > 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 rasen.dubi at gmail.com Mon Jun 15 05:28:43 2015 From: rasen.dubi at gmail.com (Alexey Shmalko) Date: Mon, 15 Jun 2015 08:28:43 +0300 Subject: [Haskell-beginners] splicing In-Reply-To: References: <557DFB8C.3070200@gmail.com> Message-ID: Yes, indeed. I forget that we're usually searching for index :) On Mon, Jun 15, 2015 at 8:05 AM, Bob Ippolito wrote: > Which works ok (still a higher constant factor, O(1) isn't free) if you want > a Bool or Maybe a answer, but if you want the index of the element you're > searching for then slicing is not the best way. > > > On Monday, June 15, 2015, Alexey Shmalko wrote: >> >> Just a quick not that slicing vectors is O(1), it doesn't copy anything. >> >> I would prefer not passing start and end indexes and use slicing because: >> 1) You won't need a wrapper function >> 2) It's mentally easier to think in terms of halves ("ok, now do >> binary search in the right half") >> >> On Mon, Jun 15, 2015 at 7:16 AM, Bob Ippolito wrote: >> > On Monday, June 15, 2015, derek riemer wrote: >> >> >> >> Hi guys, >> >> As a newby to haskell, I was curious, what is the best way to splice an >> >> array or do things in the middle? >> >> For example, binary search requires i do in sudocode >> >> define binary search array target. >> >> Find middle element. >> >> If target is middle element then return target >> >> else if target < middle element then >> >> binary search array[0:target] >> >> else >> >> binary search array[target:end] >> >> >> >> How can I get this splicing with haskell? >> >> I can't just use head here. >> >> I can't do array!!n: where n is some number. >> > >> > >> > You probably shouldn't use lists for binary search, since indexing a >> > list is >> > linear time. Binary searching a list is slower than a linear search. >> > However, if you must, you can use splitAt for that purpose. >> > >> > Where you should really be looking for Array-like uses are Data.Vector >> > or >> > Data.Array. The former is probably better suited for this use case. >> > >> > You should also consider adding arguments to the search function for >> > start >> > and end indexes, rather than slicing the array itself. That's the more >> > traditional way to implement it. >> > >> > -bob >> > >> > _______________________________________________ >> > 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 > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > From shishir.srivastava at gmail.com Mon Jun 15 11:03:24 2015 From: shishir.srivastava at gmail.com (Shishir Srivastava) Date: Mon, 15 Jun 2015 12:03:24 +0100 Subject: [Haskell-beginners] Syntax of Complex Message-ID: Hi, The Data.Complex package defines the new data type 'Complex' as ---------- data Complex a = !a :+ !a ------- Where ':+' is an infix operator. I don't however understand the usage of '!' in front of the type variable 'a'. What exactly is the purpose of '!' ? Any help would be appreciated. Thanks, Shishir Srivastava -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Mon Jun 15 11:18:22 2015 From: bob at redivi.com (Bob Ippolito) Date: Mon, 15 Jun 2015 13:18:22 +0200 Subject: [Haskell-beginners] Syntax of Complex In-Reply-To: References: Message-ID: On Monday, June 15, 2015, Shishir Srivastava wrote: > Hi, > > The Data.Complex package defines the new data type 'Complex' as > > ---------- > > data Complex a = !a :+ !a > > ------- > > Where ':+' is an infix operator. I don't however understand the usage of > '!' in front of the type variable 'a'. What exactly is the purpose of '!' ? > '!' is a strictness annotation. This means that when the value is forced to weak-head normal form (by pattern matching, BangPatterns, or seq), then the fields with the ! will also be forced to weak-head normal form. See also: http://chimera.labs.oreilly.com/books/1230000000929/ch02.html#sec_par-eval-whnf https://hackhands.com/lazy-evaluation-works-haskell/ -bob -------------- next part -------------- An HTML attachment was scrubbed... URL: From matt.williams45.mw at gmail.com Tue Jun 16 06:52:08 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Tue, 16 Jun 2015 06:52:08 +0000 Subject: [Haskell-beginners] Difference between types and values Message-ID: Dear All, I am sure this is a common mistake, and I am happy to be pointed elsewhere for reading. I have spent the last couple of days on the Haskell irc channel, which was very helpful. However, one of the points of discussion left me confused. When we have a type, T, with constructors A and B (e.g. data T = A x y z | B x y) How do I understand the relationship between A, B and T? I had thought I could use the sub-class relationship, but that doesn't seem to be true. Any other pointers very welcome. Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at vlkk.cz Tue Jun 16 07:26:16 2015 From: martin at vlkk.cz (Martin Vlk) Date: Tue, 16 Jun 2015 07:26:16 +0000 Subject: [Haskell-beginners] Difference between types and values In-Reply-To: References: Message-ID: <557FCF98.7010604@vlkk.cz> One useful way to understand this is to note you will see T in type annotations and A, B in your actual code. I.e. T is a type constructor and A, B are data constructors. M. Matt Williams: > Dear All, > > I am sure this is a common mistake, and I am happy to be pointed elsewhere > for reading. > > I have spent the last couple of days on the Haskell irc channel, which was > very helpful. > > However, one of the points of discussion left me confused. > > When we have a type, T, with constructors A and B > > (e.g. data T = A x y z | B x y) > > How do I understand the relationship between A, B and T? I had thought I > could use the sub-class relationship, but that doesn't seem to be true. > > Any other pointers very welcome. > > Matt > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > From karl at karlv.net Tue Jun 16 07:42:16 2015 From: karl at karlv.net (Karl Voelker) Date: Tue, 16 Jun 2015 00:42:16 -0700 Subject: [Haskell-beginners] Difference between types and values In-Reply-To: References: Message-ID: <1434440536.2636752.296669137.3CFA9E36@webmail.messagingengine.com> On Mon, Jun 15, 2015, at 11:52 PM, Matt Williams wrote: > When we have a type, T, with constructors A and B > (e.g. data T = A x y z | B x y) > How do I understand the relationship between A, B and T? I had > thought I could use the sub-class relationship, but that doesn't seem > to be true. You are correct that A and B are not types in Haskell. The relationship is that there are two different ways to construct a value of type T. Whenever a T is needed, you can use either A or B. That means, on the other hand, that whenever a T is consumed, you have to handle two cases: A and B. These data types are called "algebraic data types," which might help you find more to read about them. The wiki has a page: https://wiki.haskell.org/Algebraic_data_type. Lastly, as a bit of a digression, you could imagine an alternate language in which A and B are subtypes of T, such that constructor A returns a value of type A, and constructor B returns a value of type B. I'm not an expert on the theory behind all of this, but I know that doing type inference would be much harder in such a language. -Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Tue Jun 16 07:42:36 2015 From: bob at redivi.com (Bob Ippolito) Date: Tue, 16 Jun 2015 09:42:36 +0200 Subject: [Haskell-beginners] Difference between types and values In-Reply-To: References: Message-ID: T is the type. A and B are the only constructors for values of that type. A and B are not terms in the type language. T is not a term in the value language. It's simpler to consider a type without any fields in the constructor: data Bool = True | False True and False are values, Bool is the type. You can't use Bool as a constructor, and you can't use True or False as a type. When you add fields it can get a bit more confusing, because the fields of a constructor are types, so it looks like "ValueConstructor1 FieldType1 FieldType2 | ValueConstructor2 FieldType3" data PersonOrPlace = Person String | Place String To make it more clear, here the types are annotated with and the constructors annotated with [SquareBrackets]: data = [Person] | [Place] On Tue, Jun 16, 2015 at 8:52 AM, Matt Williams wrote: > Dear All, > > I am sure this is a common mistake, and I am happy to be pointed elsewhere > for reading. > > I have spent the last couple of days on the Haskell irc channel, which was > very helpful. > > However, one of the points of discussion left me confused. > > When we have a type, T, with constructors A and B > > (e.g. data T = A x y z | B x y) > > How do I understand the relationship between A, B and T? I had thought I > could use the sub-class relationship, but that doesn't seem to be true. > > Any other pointers very welcome. > > Matt > > _______________________________________________ > 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 ovidiudeac at gmail.com Tue Jun 16 08:55:13 2015 From: ovidiudeac at gmail.com (Ovidiu Deac) Date: Tue, 16 Jun 2015 11:55:13 +0300 Subject: [Haskell-beginners] Difference between types and values In-Reply-To: References: Message-ID: I want to add a little more thing that makes me understand this easier: data Bool = True | False You can think if True not as a value but as a function from unit to Bool That being said in Bob's example: data PersonOrPlace = Person String | Place String ...Person is a function from the type String to the type PersonOrPlace As a conclusion: Haskell is, as they say, "a strong & static typed purely functional language", everything is either a type or a function. If it's not a type then it must be a function. You can say that even 0 is a function from unit to Int so it works quite nice. On Tue, Jun 16, 2015 at 10:42 AM, Bob Ippolito wrote: > T is the type. A and B are the only constructors for values of that type. > A and B are not terms in the type language. T is not a term in the value > language. > > It's simpler to consider a type without any fields in the constructor: > > data Bool = True | False > > True and False are values, Bool is the type. You can't use Bool as a > constructor, and you can't use True or False as a type. > > When you add fields it can get a bit more confusing, because the fields of > a constructor are types, so it looks like "ValueConstructor1 FieldType1 > FieldType2 | ValueConstructor2 FieldType3" > > data PersonOrPlace = Person String | Place String > > To make it more clear, here the types are annotated with > and the constructors annotated with [SquareBrackets]: > > data = [Person] | [Place] > > > > On Tue, Jun 16, 2015 at 8:52 AM, Matt Williams < > matt.williams45.mw at gmail.com> wrote: > >> Dear All, >> >> I am sure this is a common mistake, and I am happy to be pointed >> elsewhere for reading. >> >> I have spent the last couple of days on the Haskell irc channel, which >> was very helpful. >> >> However, one of the points of discussion left me confused. >> >> When we have a type, T, with constructors A and B >> >> (e.g. data T = A x y z | B x y) >> >> How do I understand the relationship between A, B and T? I had thought I >> could use the sub-class relationship, but that doesn't seem to be true. >> >> Any other pointers very welcome. >> >> Matt >> >> _______________________________________________ >> 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 sumit.sahrawat.apm13 at iitbhu.ac.in Tue Jun 16 12:05:51 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Tue, 16 Jun 2015 17:35:51 +0530 Subject: [Haskell-beginners] Difference between types and values In-Reply-To: References: Message-ID: A short example: data T = Tag1 Type1 Type2 | Tag2 Type3 -- A type T can contain elements of two different types, which can be differentiated in a program by their 'Tag' -- 'Tag1 Type1 Type2' is a product type, just like a cartesian product of sets. It has elements -- of the form (Type1, Type2) but written as 'Tag1 Type1 Type2' for programming convenience. -- Tag2 Type3 is just Type3, with additional syntax to differentiate it from Type3. -- The pipe '|' creates a sum type, just like the union of sets. -- Overall, you have a type which has elements of the form (Type1, Type2) or Type3. Written differently so that -- they can be distinguished from (Type1, Type2) and Type3 elements. -- (x :: Type1, y :: Type2) is not equal to 'Tag1 x y'. -- The first has the type (Type1, Type2) and the second has the type T. -- Thus, Tag1 takes a Type1 and a Type2 and converts them to a T. -- Tag1 :: Type1 -> Type2 -> T -- A data constructor, constructs element of type T using elements of type Type1 and Type2 Read the two pages below, to get more intuition. Will be more helpful if you come from C and know about unions in that language. https://en.wikipedia.org/wiki/Algebraic_data_type https://en.wikipedia.org/wiki/Tagged_union Hope this helps. On 16 June 2015 at 14:25, Ovidiu Deac wrote: > I want to add a little more thing that makes me understand this easier: > > data Bool = True | False > > You can think if True not as a value but as a function from unit to Bool > > That being said in Bob's example: > > data PersonOrPlace = Person String | Place String > > ...Person is a function from the type String to the type PersonOrPlace > > As a conclusion: Haskell is, as they say, "a strong & static typed purely > functional language", everything is either a type or a function. If it's > not a type then it must be a function. You can say that even 0 is a > function from unit to Int so it works quite nice. > > > On Tue, Jun 16, 2015 at 10:42 AM, Bob Ippolito wrote: > >> T is the type. A and B are the only constructors for values of that type. >> A and B are not terms in the type language. T is not a term in the value >> language. >> >> It's simpler to consider a type without any fields in the constructor: >> >> data Bool = True | False >> >> True and False are values, Bool is the type. You can't use Bool as a >> constructor, and you can't use True or False as a type. >> >> When you add fields it can get a bit more confusing, because the fields >> of a constructor are types, so it looks like "ValueConstructor1 FieldType1 >> FieldType2 | ValueConstructor2 FieldType3" >> >> data PersonOrPlace = Person String | Place String >> >> To make it more clear, here the types are annotated with >> and the constructors annotated with [SquareBrackets]: >> >> data = [Person] | [Place] >> >> >> >> On Tue, Jun 16, 2015 at 8:52 AM, Matt Williams < >> matt.williams45.mw at gmail.com> wrote: >> >>> Dear All, >>> >>> I am sure this is a common mistake, and I am happy to be pointed >>> elsewhere for reading. >>> >>> I have spent the last couple of days on the Haskell irc channel, which >>> was very helpful. >>> >>> However, one of the points of discussion left me confused. >>> >>> When we have a type, T, with constructors A and B >>> >>> (e.g. data T = A x y z | B x y) >>> >>> How do I understand the relationship between A, B and T? I had thought I >>> could use the sub-class relationship, but that doesn't seem to be true. >>> >>> Any other pointers very welcome. >>> >>> Matt >>> >>> _______________________________________________ >>> 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 >> >> > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From sumit.sahrawat.apm13 at iitbhu.ac.in Tue Jun 16 12:07:12 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Tue, 16 Jun 2015 17:37:12 +0530 Subject: [Haskell-beginners] Difference between types and values In-Reply-To: References: Message-ID: Ovidiu, take a look at this eye opener: http://conal.net/blog/posts/everything-is-a-function-in-haskell On 16 June 2015 at 17:35, Sumit Sahrawat, Maths & Computing, IIT (BHU) < sumit.sahrawat.apm13 at iitbhu.ac.in> wrote: > A short example: > > data T = Tag1 Type1 Type2 > | Tag2 Type3 > > -- A type T can contain elements of two different types, which can be > differentiated in a program by their 'Tag' > > -- 'Tag1 Type1 Type2' is a product type, just like a cartesian product > of sets. It has elements > -- of the form (Type1, Type2) but written as 'Tag1 Type1 Type2' for > programming convenience. > > -- Tag2 Type3 is just Type3, with additional syntax to differentiate > it from Type3. > > -- The pipe '|' creates a sum type, just like the union of sets. > > -- Overall, you have a type which has elements of the form (Type1, > Type2) or Type3. Written differently so that > -- they can be distinguished from (Type1, Type2) and Type3 elements. > > -- (x :: Type1, y :: Type2) is not equal to 'Tag1 x y'. > -- The first has the type (Type1, Type2) and the second has the type T. > -- Thus, Tag1 takes a Type1 and a Type2 and converts them to a T. > > -- Tag1 :: Type1 -> Type2 -> T > -- A data constructor, constructs element of type T using elements of > type Type1 and Type2 > > Read the two pages below, to get more intuition. Will be more helpful if > you come from C and know about unions in that language. > > https://en.wikipedia.org/wiki/Algebraic_data_type > https://en.wikipedia.org/wiki/Tagged_union > > Hope this helps. > > On 16 June 2015 at 14:25, Ovidiu Deac wrote: > >> I want to add a little more thing that makes me understand this easier: >> >> data Bool = True | False >> >> You can think if True not as a value but as a function from unit to Bool >> >> That being said in Bob's example: >> >> data PersonOrPlace = Person String | Place String >> >> ...Person is a function from the type String to the type PersonOrPlace >> >> As a conclusion: Haskell is, as they say, "a strong & static typed purely >> functional language", everything is either a type or a function. If it's >> not a type then it must be a function. You can say that even 0 is a >> function from unit to Int so it works quite nice. >> >> >> On Tue, Jun 16, 2015 at 10:42 AM, Bob Ippolito wrote: >> >>> T is the type. A and B are the only constructors for values of that >>> type. A and B are not terms in the type language. T is not a term in the >>> value language. >>> >>> It's simpler to consider a type without any fields in the constructor: >>> >>> data Bool = True | False >>> >>> True and False are values, Bool is the type. You can't use Bool as a >>> constructor, and you can't use True or False as a type. >>> >>> When you add fields it can get a bit more confusing, because the fields >>> of a constructor are types, so it looks like "ValueConstructor1 FieldType1 >>> FieldType2 | ValueConstructor2 FieldType3" >>> >>> data PersonOrPlace = Person String | Place String >>> >>> To make it more clear, here the types are annotated with >>> and the constructors annotated with [SquareBrackets]: >>> >>> data = [Person] | [Place] >>> >>> >>> >>> On Tue, Jun 16, 2015 at 8:52 AM, Matt Williams < >>> matt.williams45.mw at gmail.com> wrote: >>> >>>> Dear All, >>>> >>>> I am sure this is a common mistake, and I am happy to be pointed >>>> elsewhere for reading. >>>> >>>> I have spent the last couple of days on the Haskell irc channel, which >>>> was very helpful. >>>> >>>> However, one of the points of discussion left me confused. >>>> >>>> When we have a type, T, with constructors A and B >>>> >>>> (e.g. data T = A x y z | B x y) >>>> >>>> How do I understand the relationship between A, B and T? I had thought >>>> I could use the sub-class relationship, but that doesn't seem to be true. >>>> >>>> Any other pointers very welcome. >>>> >>>> Matt >>>> >>>> _______________________________________________ >>>> 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 >>> >>> >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > > > -- > Regards > > Sumit Sahrawat > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From defigueiredo at ucdavis.edu Wed Jun 17 00:43:38 2015 From: defigueiredo at ucdavis.edu (Dimitri DeFigueiredo) Date: Tue, 16 Jun 2015 18:43:38 -0600 Subject: [Haskell-beginners] phantom types and record syntax Message-ID: <5580C2BA.2080100@ucdavis.edu> Hi All, I am a little suprised that this program compiles in GHC: ---- data ReqTime = ReqTime data AckTime = AckTime data Order a = Order { price ::Double, volume ::Int, timestamp ::Int } convertToReq :: Order AckTime -> Order ReqTime convertToReq o = o{price = 1} main = putStrLn "Hi!" ---- My trouble is that it seems the record syntax is *implicitly* converting from one type to the other. It seems I would have to remove the phantom type to avoid this: ---- data Order a = Order { price ::Double, volume ::Int, timestamp ::Int, myType :: a } convertToReq :: Order AckTime -> Order ReqTime convertToReq o = o{price = 1} -- fail!! ---- Could somebody sprinkle some insight into why this is "converted automatically" for phantom types? Can I avoid this behavior? Thanks! Dimitri From akaberto at gmail.com Wed Jun 17 04:14:03 2015 From: akaberto at gmail.com (akash g) Date: Wed, 17 Jun 2015 09:44:03 +0530 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: <5580C2BA.2080100@ucdavis.edu> References: <5580C2BA.2080100@ucdavis.edu> Message-ID: The phantom type doesn't appear on the actual constructors, only on the type signatures. In the function convertToReq, you are changing the following 1. The type. 2. The value of the price record (actually returning a new value with the price record changed to one and the rest of the fields being the same. That said, I don't see the point of a phantom on a record structure like this. Phantoms are more useful when you have multiple data constructors for a given type and you want to make sure you don't have constructions that don't make sense. Like in an interpreter, you don't want to create expressions that can give rise to an expressions like add a integer to a string and that sort of thing. Try this: http://www.scs.stanford.edu/11au-cs240h/notes/laziness-slides.html In fact, that set of lecture notes as well as the 2014 class notes are amazingly good. On Wed, Jun 17, 2015 at 6:13 AM, Dimitri DeFigueiredo < defigueiredo at ucdavis.edu> wrote: > Hi All, > > I am a little suprised that this program compiles in GHC: > > ---- > data ReqTime = ReqTime > data AckTime = AckTime > > data Order a = Order { price ::Double, volume ::Int, timestamp ::Int } > > convertToReq :: Order AckTime -> Order ReqTime > convertToReq o = o{price = 1} > > main = putStrLn "Hi!" > ---- > > My trouble is that it seems the record syntax is *implicitly* converting > from one type to the other. It seems I would have to remove the phantom > type to avoid this: > > ---- > data Order a = Order { price ::Double, volume ::Int, timestamp ::Int, > myType :: a } > > convertToReq :: Order AckTime -> Order ReqTime > convertToReq o = o{price = 1} -- fail!! > ---- > > Could somebody sprinkle some insight into why this is "converted > automatically" for phantom types? Can I avoid this behavior? > > Thanks! > > Dimitri > _______________________________________________ > 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 allbery.b at gmail.com Wed Jun 17 04:55:38 2015 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 17 Jun 2015 00:55:38 -0400 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: References: <5580C2BA.2080100@ucdavis.edu> Message-ID: On Wed, Jun 17, 2015 at 12:14 AM, akash g wrote: > The phantom type doesn't appear on the actual constructors, only on the > type signatures. In the function convertToReq, you are changing the > following > 1. The type. > 2. The value of the price record (actually returning a new value with the > price record changed to one and the rest of the fields being the same. > I'm not sure I see the difference between the given example and the "effectively phantom" type in foo :: Maybe String -> Maybe Int foo x at Nothing = x -- error: Nothing :: Maybe String is not compatible with Maybe Int foo x = ... -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From akaberto at gmail.com Wed Jun 17 05:34:51 2015 From: akaberto at gmail.com (akash g) Date: Wed, 17 Jun 2015 11:04:51 +0530 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: References: <5580C2BA.2080100@ucdavis.edu> Message-ID: When you have phantom types, you get can catch logically illegal functions in the type itself. You can create constructors for types so that you can't create illegal expressions. ----------------- data Expr = Num Int -- atom | Str String -- atom | Op BinOp Expr Expr -- compound deriving (Show) data BinOp = Add | Concat deriving (Show) data Expr1 a = Num1 Int -- atom | Str1 String -- atom | Op1 BinOp (Expr1 a) (Expr1 a) -- compound deriving (Show) addition :: Expr1 Int -> Expr1 Int -> Expr1 Int addition (Num1 a) (Num1 b) = Num1 $ a + b createNum :: Int -> Expr createNum a = Num a createStr :: String -> Expr createStr a = Str a createNum1 :: Int -> Expr1 Int createNum1 a = Num1 a createStr1 :: String -> Expr1 String createStr1 a = Str1 a sumExpr :: Expr -> Expr -> Expr sumExpr a b = Op Add a b sumExpr1 :: Expr1 Int -> Expr1 Int -> Expr1 Int sumExpr1 a b = Op1 Add a b ----------------- With the above, you can create expressions that make no sense in real life (like adding/concating a number to a string ). When I execute this in GHCI, I get the following -------- ?> sumExpr (createNum 1) (createStr "a") Op Add (Num 1) (Str "a") ?> sumExpr1 (createNum1 1) (createStr1 "a") :342:26-39: Couldn't match type ?[Char]? with ?Int? Expected type: Expr1 Int Actual type: Expr1 String In the second argument of ?sumExpr1?, namely ?(createStr1 "a")? In the expression: sumExpr1 (createNum1 1) (createStr1 "a") ?> -------- >From the above, it is clear that as long as we write constructors taking into account the types (called smart-constructors), we can prevent expressions from being created. I do admit that this makes it a bit tedious as we would have to write the constructors by hand, but we get type level guarantees. I think GADTs are much better for things like this for specifying the constructors, but you'd still have to write sumExpr1 in program. On Wed, Jun 17, 2015 at 10:25 AM, Brandon Allbery wrote: > On Wed, Jun 17, 2015 at 12:14 AM, akash g wrote: > >> The phantom type doesn't appear on the actual constructors, only on the >> type signatures. In the function convertToReq, you are changing the >> following >> 1. The type. >> 2. The value of the price record (actually returning a new value with the >> price record changed to one and the rest of the fields being the same. >> > > I'm not sure I see the difference between the given example and the > "effectively phantom" type in > > foo :: Maybe String -> Maybe Int > foo x at Nothing = x -- error: Nothing :: Maybe String is not compatible > with Maybe Int > foo x = ... > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > > _______________________________________________ > 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 akaberto at gmail.com Wed Jun 17 05:38:12 2015 From: akaberto at gmail.com (akash g) Date: Wed, 17 Jun 2015 11:08:12 +0530 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: References: <5580C2BA.2080100@ucdavis.edu> Message-ID: Oh, and the above data types were lifted from Stanford's cs240h (the 2011 version). On Wed, Jun 17, 2015 at 11:04 AM, akash g wrote: > When you have phantom types, you get can catch logically illegal functions > in the type itself. You can create constructors for types so that you > can't create illegal expressions. > ----------------- > data Expr = Num Int -- atom > | Str String -- atom > | Op BinOp Expr Expr -- compound > deriving (Show) > > data BinOp = Add | Concat > deriving (Show) > > data Expr1 a = Num1 Int -- atom > | Str1 String -- atom > | Op1 BinOp (Expr1 a) (Expr1 a) -- compound > deriving (Show) > > addition :: Expr1 Int -> Expr1 Int -> Expr1 Int > addition (Num1 a) (Num1 b) = Num1 $ a + b > > createNum :: Int -> Expr > createNum a = Num a > > createStr :: String -> Expr > createStr a = Str a > > createNum1 :: Int -> Expr1 Int > createNum1 a = Num1 a > > > createStr1 :: String -> Expr1 String > createStr1 a = Str1 a > > > sumExpr :: Expr -> Expr -> Expr > sumExpr a b = Op Add a b > > sumExpr1 :: Expr1 Int -> Expr1 Int -> Expr1 Int > sumExpr1 a b = Op1 Add a b > > ----------------- > > With the above, you can create expressions that make no sense in real life > (like adding/concating a number to a string ). When I execute this in > GHCI, I get the following > > -------- > ?> sumExpr (createNum 1) (createStr "a") > Op Add (Num 1) (Str "a") > ?> sumExpr1 (createNum1 1) (createStr1 "a") > > :342:26-39: > Couldn't match type ?[Char]? with ?Int? > Expected type: Expr1 Int > Actual type: Expr1 String > In the second argument of ?sumExpr1?, namely ?(createStr1 "a")? > In the expression: sumExpr1 (createNum1 1) (createStr1 "a") > ?> > -------- > > From the above, it is clear that as long as we write constructors taking > into account the types (called smart-constructors), we can prevent > expressions from being created. I do admit that this makes it a bit > tedious as we would have to write the constructors by hand, but we get type > level guarantees. > > I think GADTs are much better for things like this for specifying the > constructors, but you'd still have to write sumExpr1 in program. > > > On Wed, Jun 17, 2015 at 10:25 AM, Brandon Allbery > wrote: > >> On Wed, Jun 17, 2015 at 12:14 AM, akash g wrote: >> >>> The phantom type doesn't appear on the actual constructors, only on the >>> type signatures. In the function convertToReq, you are changing the >>> following >>> 1. The type. >>> 2. The value of the price record (actually returning a new value with >>> the price record changed to one and the rest of the fields being the same. >>> >> >> I'm not sure I see the difference between the given example and the >> "effectively phantom" type in >> >> foo :: Maybe String -> Maybe Int >> foo x at Nothing = x -- error: Nothing :: Maybe String is not >> compatible with Maybe Int >> foo x = ... >> >> -- >> brandon s allbery kf8nh sine nomine >> associates >> allbery.b at gmail.com >> ballbery at sinenomine.net >> unix, openafs, kerberos, infrastructure, xmonad >> http://sinenomine.net >> >> _______________________________________________ >> 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 karl at karlv.net Wed Jun 17 06:42:06 2015 From: karl at karlv.net (Karl Voelker) Date: Tue, 16 Jun 2015 23:42:06 -0700 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: <5580C2BA.2080100@ucdavis.edu> References: <5580C2BA.2080100@ucdavis.edu> Message-ID: <1434523326.2978810.297687737.0022A033@webmail.messagingengine.com> On Tue, Jun 16, 2015, at 05:43 PM, Dimitri DeFigueiredo wrote: > I am a little suprised that this program compiles in GHC: > > ---- > data ReqTime = ReqTime > data AckTime = AckTime > > data Order a = Order { price ::Double, volume ::Int, timestamp ::Int } > > convertToReq :: Order AckTime -> Order ReqTime > convertToReq o = o{price = 1} > > main = putStrLn "Hi!" > ---- I found it surprising, too. But, if you look in the Haskell report (https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-540003.15.3), record update is defined by a "desugaring" translation. So your convertToReq desugars (roughly) to: convertToReq o = case o of Order v1 v2 v3 -> Order 1 v2 v3 Unfortunately, the report does not have any commentary on why it is the way it is. -Karl From defigueiredo at ucdavis.edu Thu Jun 18 02:21:20 2015 From: defigueiredo at ucdavis.edu (Dimitri DeFigueiredo) Date: Wed, 17 Jun 2015 20:21:20 -0600 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: <1434523326.2978810.297687737.0022A033@webmail.messagingengine.com> References: <5580C2BA.2080100@ucdavis.edu> <1434523326.2978810.297687737.0022A033@webmail.messagingengine.com> Message-ID: <55822B20.8020501@ucdavis.edu> Thanks for the thoughts. This is funny, so the constructor has the same name but is for different types. I think this is specially bad for security. I'm going to be paranoid about it now. Dimitri On 17/06/15 00:42, Karl Voelker wrote: > On Tue, Jun 16, 2015, at 05:43 PM, Dimitri DeFigueiredo wrote: >> I am a little suprised that this program compiles in GHC: >> >> ---- >> data ReqTime = ReqTime >> data AckTime = AckTime >> >> data Order a = Order { price ::Double, volume ::Int, timestamp ::Int } >> >> convertToReq :: Order AckTime -> Order ReqTime >> convertToReq o = o{price = 1} >> >> main = putStrLn "Hi!" >> ---- > I found it surprising, too. But, if you look in the Haskell report > (https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-540003.15.3), > record update is defined by a "desugaring" translation. So your > convertToReq desugars (roughly) to: > > convertToReq o = case o of > Order v1 v2 v3 -> Order 1 v2 v3 > > Unfortunately, the report does not have any commentary on why it is the > way it is. > > -Karl > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From karl at karlv.net Thu Jun 18 04:42:32 2015 From: karl at karlv.net (Karl Voelker) Date: Wed, 17 Jun 2015 21:42:32 -0700 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: <55822B20.8020501@ucdavis.edu> References: <5580C2BA.2080100@ucdavis.edu> <1434523326.2978810.297687737.0022A033@webmail.messagingengine.com> <55822B20.8020501@ucdavis.edu> Message-ID: <1434602552.3301193.298646825.2D24F878@webmail.messagingengine.com> On Wed, Jun 17, 2015, at 07:21 PM, Dimitri DeFigueiredo wrote: > This is funny, so the constructor has the same name but is for different > types. I think this is specially bad for security. I'm going to be > paranoid about it now. If you would like to give some more background on your use case, we may be able to suggest better ways to ensure safety through types. -Karl From imantc at gmail.com Thu Jun 18 08:04:12 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 18 Jun 2015 10:04:12 +0200 Subject: [Haskell-beginners] phantom types and record syntax In-Reply-To: <1434602552.3301193.298646825.2D24F878@webmail.messagingengine.com> References: <5580C2BA.2080100@ucdavis.edu> <1434523326.2978810.297687737.0022A033@webmail.messagingengine.com> <55822B20.8020501@ucdavis.edu> <1434602552.3301193.298646825.2D24F878@webmail.messagingengine.com> Message-ID: function signature makes a difference. in this example, try swapping the signature of function convertToReq it seems implicit conversion happens depending on signature (and usual constraints), yes module Phantom where data ReqTime = ReqTime data AckTime = AckTime -- convertToReq :: Order AckTime -> Order ReqTime -- builds convertToReq :: Order AckTime -> Order AckTime -- error convertToReq o = o{price = 1} data Order a = Order { price ::Double, volume ::Int, timestamp ::Int } main :: Order ReqTime main = expectReq conv where ack = initAckTime conv = convertToReq ack initAckTime:: Order AckTime initAckTime = Order { timestamp = 0, price = 2.1, volume = 3 } expectReq::Order ReqTime -> Order ReqTime expectReq o = o From chaddai.fouche at gmail.com Thu Jun 18 17:48:24 2015 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Thu, 18 Jun 2015 17:48:24 +0000 Subject: [Haskell-beginners] [Haskell-cafe] phantom types and record syntax In-Reply-To: <558230CE.2020806@ucdavis.edu> References: <558230CE.2020806@ucdavis.edu> Message-ID: Le jeu. 18 juin 2015 ? 04:45, Dimitri DeFigueiredo a ?crit : > I am surprised that this program compiles in GHC: > > snip > > My trouble is that it seems the record syntax is *implicitly* converting > from one type to the other. It seems I would have to remove the phantom > type by adding a tag to avoid this: > This is faulty reasoning because it imply that a value changed type in your code, based on your understanding that the record syntax is "changing" a value... This is not the case ! Haskell is functional, immutability is the rule. The record syntax is just a shortcut to create a new value sharing some of its parts with the old value. It is thus perfectly normal that the type of this new value can be different of the type of the old value if no other constraint prevent this (and Phantom types are by essence unconstrained by the value, that is why they're "Phantom"). > > But this makes me unwilling to use phantom types for security as I would > be worried of unwittingly making the conversion. > > The value of Phantom types is generally only displayed if you make them abstract types, since the only way to constrain the phantom type is by imposing restrictive signatures for your handling functions (and then using those restricted functions)... This is why you usually won't export the constructors, only smart constructors that can only produce a precise type of value with the right phantom type. In these conditions, you can't "unwittingly make a conversion" and your API impose a safe pattern of use, helped by the type system to interdict unsafe combination without any runtime cost. > > Could somebody sprinkle some insight into why this is "converted > automatically" for phantom types? > Is there another way around this? > > As I said, your perspective is wrong : there is no "conversion" here, simply a new value with a new type. I really fail to see why you would want your program to fail to compile, your "sanitize" is exactly the kind of function Phantom types are for : supposing you can only create "Username UserSupplied" with your API, and a part of your API only accept "Username Safe", you'll need a function like sanitize to bridge those two parts. -- Jeda? -------------- next part -------------- An HTML attachment was scrubbed... URL: From sbarak.sb at gmail.com Fri Jun 19 00:39:46 2015 From: sbarak.sb at gmail.com (steve barak) Date: Thu, 18 Jun 2015 17:39:46 -0700 Subject: [Haskell-beginners] (no subject) Message-ID: Unsubscribe me already!!! Steve Barak -------------- next part -------------- An HTML attachment was scrubbed... URL: From sumit.sahrawat.apm13 at iitbhu.ac.in Fri Jun 19 00:40:20 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Fri, 19 Jun 2015 06:10:20 +0530 Subject: [Haskell-beginners] (no subject) In-Reply-To: References: Message-ID: http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners On 19 June 2015 at 06:09, steve barak wrote: > Unsubscribe me already!!! > > Steve Barak > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From matt.williams45.mw at gmail.com Fri Jun 19 05:51:59 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Fri, 19 Jun 2015 05:51:59 +0000 Subject: [Haskell-beginners] Adapting code from an imperative loop Message-ID: Dear All, I have been wrestling with this for a while now. I have a list of data items, and want to be able to access them, in a Hash Map, via a short summary of their characteristics. In an imperative language this might look like: myMap = new map() for elem in myElems: key = makeKey(elem) myMap[key] = myMap[key] + elem I have been trying to do this in Haskell, but am stuck on how to hand the Map back to itself each time. I have a function :: elem -> [p,q] to make the key, but the Map.insert function has the following signature: insert :: (Hashable k, Ord k) => k -> a -> HashMap k a -> HashMap k a My thought was that I needed to go through the list of the elems, and at each point add them to the Hash Map, handing the updated Map onto the next step - but this is what I cannot write. Any help much appreciated. Thanks, Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Fri Jun 19 06:18:45 2015 From: bob at redivi.com (Bob Ippolito) Date: Fri, 19 Jun 2015 08:18:45 +0200 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: References: Message-ID: On Friday, June 19, 2015, Matt Williams wrote: > Dear All, > > I have been wrestling with this for a while now. > > I have a list of data items, and want to be able to access them, in a Hash > Map, via a short summary of their characteristics. > > In an imperative language this might look like: > > myMap = new map() > for elem in myElems: > key = makeKey(elem) > myMap[key] = myMap[key] + elem > > I have been trying to do this in Haskell, but am stuck on how to hand the > Map back to itself each time. > > I have a function :: elem -> [p,q] to make the key, but the Map.insert > function has the following signature: > > insert :: (Hashable > > k, Ord > k) > => k -> a -> HashMap > k > a -> HashMap > k > a > > My thought was that I needed to go through the list of the elems, and at > each point add them to the Hash Map, handing the updated Map onto the next > step - but this is what I cannot write. > This is typically done with fromListWith or a combination of foldl' and insertWith or alter. -bob -------------- next part -------------- An HTML attachment was scrubbed... URL: From matt.williams45.mw at gmail.com Fri Jun 19 07:05:53 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Fri, 19 Jun 2015 07:05:53 +0000 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: References: Message-ID: I tried doing it as a fold (the pattern of accumulating a value, where the accumulated value was the resulting Map), but couldn't manage the syntax. Have now got it partially working with fromListWith. Thanks a lot, Matt On Fri, 19 Jun 2015 07:18 Bob Ippolito wrote: > On Friday, June 19, 2015, Matt Williams > wrote: > >> Dear All, >> >> I have been wrestling with this for a while now. >> >> I have a list of data items, and want to be able to access them, in a >> Hash Map, via a short summary of their characteristics. >> >> In an imperative language this might look like: >> >> myMap = new map() >> for elem in myElems: >> key = makeKey(elem) >> myMap[key] = myMap[key] + elem >> >> I have been trying to do this in Haskell, but am stuck on how to hand the >> Map back to itself each time. >> >> I have a function :: elem -> [p,q] to make the key, but the Map.insert >> function has the following signature: >> >> insert :: (Hashable >> >> k, Ord >> k) >> => k -> a -> HashMap >> k >> a -> HashMap >> k >> a >> >> My thought was that I needed to go through the list of the elems, and at >> each point add them to the Hash Map, handing the updated Map onto the next >> step - but this is what I cannot write. >> > > This is typically done with fromListWith or a combination of foldl' and > insertWith or alter. > > -bob > _______________________________________________ > 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 vlatko.basic at gmail.com Fri Jun 19 08:04:30 2015 From: vlatko.basic at gmail.com (Vlatko Basic) Date: Fri, 19 Jun 2015 10:04:30 +0200 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: References: Message-ID: <5583CD0E.604@gmail.com> An HTML attachment was scrubbed... URL: From matt.williams45.mw at gmail.com Fri Jun 19 09:52:42 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Fri, 19 Jun 2015 09:52:42 +0000 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: <5583CD0E.604@gmail.com> References: <5583CD0E.604@gmail.com> Message-ID: Dear All, Thanks for your help with this. I have got the simple version working but now need to use Map.fromListWith, and am having syntax problems. I found a related question on Stack overflow (here: http:// stackoverflow.com /questions/15514486/ haskell-converting-a-list- of- a-b-key- value-pairs- with- possibly- repeated-key ). However, I'm having problems understanding the additional function. The signature should be : (a -> a -> a) -> [(k, a)] -> Map And so I assume I need to supply a function whose signature is: (a -> a -> a) Is that correct? Thanks, Matt On Fri, 19 Jun 2015 09:04 Vlatko Basic wrote: > To learn, I'd suggest you implement it first with the recursion (a tip: > use a "loop" function in where clause), and than with fold. Those are > important features to understand in Haskell. Try to use the "higher-level" > functions as little as possible until you grasp the basics (like fold > syntax). > > If you just need any solution, fromListWith is fine. > > br, > vlatko > > > > -------- Original Message -------- > Subject: Re: [Haskell-beginners] Adapting code from an imperative loop > From: Matt Williams > > To: The Haskell-Beginners Mailing List - Discussion of primarily > beginner-level topics related to Haskell > > Date: 19/06/15 09:05 > > > I tried doing it as a fold (the pattern of accumulating a value, where > the accumulated value was the resulting Map), but couldn't manage the > syntax. > > Have now got it partially working with fromListWith. > > Thanks a lot, > Matt > > On Fri, 19 Jun 2015 07:18 Bob Ippolito wrote: > >> On Friday, June 19, 2015, Matt Williams >> wrote: >> >>> Dear All, >>> >>> I have been wrestling with this for a while now. >>> >>> I have a list of data items, and want to be able to access them, in a >>> Hash Map, via a short summary of their characteristics. >>> >>> In an imperative language this might look like: >>> >>> myMap = new map() >>> for elem in myElems: >>> key = makeKey(elem) >>> myMap[key] = myMap[key] + elem >>> >>> I have been trying to do this in Haskell, but am stuck on how to hand >>> the Map back to itself each time. >>> >>> I have a function :: elem -> [p,q] to make the key, but the Map.insert >>> function has the following signature: >>> >>> insert :: (Hashable >>> >>> k, Ord >>> k) >>> => k -> a -> HashMap >>> k >>> a -> HashMap >>> k >>> a >>> >>> My thought was that I needed to go through the list of the elems, and at >>> each point add them to the Hash Map, handing the updated Map onto the next >>> step - but this is what I cannot write. >>> >> >> This is typically done with fromListWith or a combination of foldl' and >> insertWith or alter. >> >> -bob >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > > > _______________________________________________ > Beginners mailing listBeginners at haskell.orghttp://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 bob at redivi.com Fri Jun 19 12:18:33 2015 From: bob at redivi.com (Bob Ippolito) Date: Fri, 19 Jun 2015 14:18:33 +0200 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: References: <5583CD0E.604@gmail.com> Message-ID: An example of a function of (a -> a -> a) would be (+), which works if your values are numbers (which mirrors your Python-like pseudocode). On Friday, June 19, 2015, Matt Williams wrote: > Dear All, > > Thanks for your help with this. > > I have got the simple version working but now need to use > Map.fromListWith, and am having syntax problems. > > I found a related question on Stack overflow (here: http:// > > stackoverflow.com > > /questions/15514486/ > > haskell-converting-a-list- > > of- > > a-b-key- > > value-pairs- > > with- > > possibly- > > repeated-key > > ). > > However, I'm having problems understanding the additional function. The > signature should be : > (a -> a -> a) -> [(k, a)] -> Map > > And so I assume I need to supply a function whose signature is: > > (a -> a -> a) > > Is that correct? > > Thanks, > Matt > > On Fri, 19 Jun 2015 09:04 Vlatko Basic > wrote: > >> To learn, I'd suggest you implement it first with the recursion (a tip: >> use a "loop" function in where clause), and than with fold. Those are >> important features to understand in Haskell. Try to use the "higher-level" >> functions as little as possible until you grasp the basics (like fold >> syntax). >> >> If you just need any solution, fromListWith is fine. >> >> br, >> vlatko >> >> >> >> -------- Original Message -------- >> Subject: Re: [Haskell-beginners] Adapting code from an imperative loop >> From: Matt Williams >> >> To: The Haskell-Beginners Mailing List - Discussion of primarily >> beginner-level topics related to Haskell >> >> Date: 19/06/15 09:05 >> >> >> I tried doing it as a fold (the pattern of accumulating a value, where >> the accumulated value was the resulting Map), but couldn't manage the >> syntax. >> >> Have now got it partially working with fromListWith. >> >> Thanks a lot, >> Matt >> >> On Fri, 19 Jun 2015 07:18 Bob Ippolito < >> bob at redivi.com >> > wrote: >> >>> On Friday, June 19, 2015, Matt Williams >> > wrote: >>> >>>> Dear All, >>>> >>>> I have been wrestling with this for a while now. >>>> >>>> I have a list of data items, and want to be able to access them, in a >>>> Hash Map, via a short summary of their characteristics. >>>> >>>> In an imperative language this might look like: >>>> >>>> myMap = new map() >>>> for elem in myElems: >>>> key = makeKey(elem) >>>> myMap[key] = myMap[key] + elem >>>> >>>> I have been trying to do this in Haskell, but am stuck on how to hand >>>> the Map back to itself each time. >>>> >>>> I have a function :: elem -> [p,q] to make the key, but the Map.insert >>>> function has the following signature: >>>> >>>> insert :: (Hashable >>>> >>>> k, Ord >>>> k) >>>> => k -> a -> HashMap >>>> k >>>> a -> HashMap >>>> k >>>> a >>>> >>>> My thought was that I needed to go through the list of the elems, and >>>> at each point add them to the Hash Map, handing the updated Map onto the >>>> next step - but this is what I cannot write. >>>> >>> >>> This is typically done with fromListWith or a combination of foldl' >>> and insertWith or alter. >>> >>> -bob >>> _______________________________________________ >>> Beginners mailing list >>> Beginners at haskell.org >>> >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >>> >> >> >> _______________________________________________ >> Beginners mailing listBeginners 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 imantc at gmail.com Fri Jun 19 12:43:47 2015 From: imantc at gmail.com (Imants Cekusins) Date: Fri, 19 Jun 2015 14:43:47 +0200 Subject: [Haskell-beginners] 'Simple' function In-Reply-To: References: <716D25E9-1290-4CD1-A6CC-2FBAA5D04EAA@yahoo.co.uk> <55786A3A.7000209@gmail.com> <417D585D-1093-4F29-806E-42ED4CBBF542@yahoo.co.uk> Message-ID: impossible: asString :: IO String -> String here is an article which in addition to this thread clarified it for me: https://wiki.haskell.org/All_About_Monads search for: 4.3 No way out The IO monad is a familiar example of a one-way monad in Haskell. Because you can't escape from the IO monad, it is impossible to write a function that does a computation in the IO monad but whose result type does not include the IO type constructor. This means that any function whose result type does not contain the IO type constructor is guaranteed not to use the IO monad. ... There is no way to get rid of the IO type constructor in the signature of any function that uses it, so the IO type constructor acts as a kind of tag that identifies all functions that do I/O. Furthermore, such functions are only useful within the IO monad. So a one-way monad effectively creates an isolated computational domain in which the rules of a pure functional language can be relaxed. Functional computations can move into the domain, but dangerous side-effects and non-referentially-transparent functions cannot escape from it. From michael at orlitzky.com Fri Jun 19 17:05:20 2015 From: michael at orlitzky.com (Michael Orlitzky) Date: Fri, 19 Jun 2015 13:05:20 -0400 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: References: Message-ID: <55844BD0.90508@orlitzky.com> On 06/19/2015 01:51 AM, Matt Williams wrote: > > In an imperative language this might look like: > > myMap = new map() > for elem in myElems: > key = makeKey(elem) > myMap[key] = myMap[key] + elem > > ... > > My thought was that I needed to go through the list of the elems, and at > each point add them to the Hash Map, handing the updated Map onto the > next step - but this is what I cannot write. > Your thought was right. You want to go through the list of elems, building up a new value (the hash map) as you go. The pattern is called a fold, as others have mentioned. The only tricky part is gluing together the pieces. Your pseudocode above looks like it assumes that myMap[key] will return zero if `key` isn't present in `myMap`. I think I've managed to reproduce what you want. The "key from element" function I used is just the identity function, but you should be able to adapt it. module Main where import Data.Map (Map, empty, insert) import qualified Data.Map as M (lookup) key_from_elem :: Int -> Int key_from_elem = id loop :: [Int] -> (Map Int Int) -> (Map Int Int) loop elems initial_map = foldr update_map initial_map elems where update_map :: Int -> (Map Int Int) -> (Map Int Int) update_map x m = let k = key_from_elem x in case (M.lookup k m) of Nothing -> insert k x m Just v -> insert k (v + x) m main :: IO () main = do let elems = [1,2,3,4,5] let l1 = loop elems empty print l1 let l2 = loop elems l1 print l2 let l3 = loop elems l2 print l3 From chaddai.fouche at gmail.com Fri Jun 19 18:49:29 2015 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Fri, 19 Jun 2015 18:49:29 +0000 Subject: [Haskell-beginners] Adapting code from an imperative loop In-Reply-To: <55844BD0.90508@orlitzky.com> References: <55844BD0.90508@orlitzky.com> Message-ID: Le ven. 19 juin 2015 ? 19:03, Michael Orlitzky a ?crit : > loop :: [Int] -> (Map Int Int) -> (Map Int Int) > loop elems initial_map = > foldr update_map initial_map elems > where > update_map :: Int -> (Map Int Int) -> (Map Int Int) > update_map x m = > let k = key_from_elem x in > case (M.lookup k m) of > Nothing -> insert k x m > Just v -> insert k (v + x) m > While this code will do the right thing, it won't do it efficiently, at all ! First (and huge) problem is using foldr : starting from the end of the list is the wrong move here if you want to consume your Int stream efficiently (which you probably do and which is vital if the stream is big). So you should be using foldl' and the strict version of Map (Data.Map.Strict). Also, though less important, looking up a key then updating the value with insert is wasteful : you will be doing the search twice, instead of using one of the nice combinators of Data.Map which find and update a value in one pass like "insertWith (+) k x m" In other words : import qualified Data.Map.Strict as M countingMap :: [(key, Int)] -> Map key Int countingMap kvs = foldl' update M.empty kvs where update (k,v) m = M.insertWith (+) k v m Since this is a very common need, there's even a combinator to do this : countingMap :: [(key, Int)] -> Map key Int countingMap kvs = M.fromListWith (+) kvs At which point you may even use directly this code and forgo creating a function for it (except if you're using it several times or as a minor step in a big pipeline where you would like to label each step clearly). -- Jeda? -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at vlkk.cz Sat Jun 20 07:19:00 2015 From: martin at vlkk.cz (Martin Vlk) Date: Sat, 20 Jun 2015 07:19:00 +0000 Subject: [Haskell-beginners] Haskell -> JavaScript -> nodejs Message-ID: <558513E4.2070600@vlkk.cz> Hi, I can successfully compile a basic Hello World into JavaScript with ghcjs and run it with nodejs. But what I ultimately need to do is write a nodejs module in Haskell and compile down to JavaScript with ghcjs. I need to be able to require other nodejs modules as well. Could somebody point me in the right direction? E.g. what approach and libraries to use... I have tried a simple thing with jsaddle/lens, but when I try to compile with ghcjs it is not finding the imported modules, even though when compiling with ghc it does find them (they are installed using cabal). Many Thanks Martin From martin at vlkk.cz Sat Jun 20 09:56:42 2015 From: martin at vlkk.cz (Martin Vlk) Date: Sat, 20 Jun 2015 09:56:42 +0000 Subject: [Haskell-beginners] Haskell -> JavaScript -> nodejs In-Reply-To: <558513E4.2070600@vlkk.cz> References: <558513E4.2070600@vlkk.cz> Message-ID: <558538DA.8030002@vlkk.cz> I made some progress - in order for Haskell modules to work with ghcjs you need to use cabal with the --ghcjs flag to install them. Martin Martin Vlk: > Hi, > I can successfully compile a basic Hello World into JavaScript with > ghcjs and run it with nodejs. > But what I ultimately need to do is write a nodejs module in Haskell and > compile down to JavaScript with ghcjs. I need to be able to require > other nodejs modules as well. > > Could somebody point me in the right direction? E.g. what approach and > libraries to use... > > I have tried a simple thing with jsaddle/lens, but when I try to compile > with ghcjs it is not finding the imported modules, even though when > compiling with ghc it does find them (they are installed using cabal). > > Many Thanks > Martin > From sumit.sahrawat.apm13 at iitbhu.ac.in Sat Jun 20 17:25:32 2015 From: sumit.sahrawat.apm13 at iitbhu.ac.in (Sumit Sahrawat, Maths & Computing, IIT (BHU)) Date: Sat, 20 Jun 2015 22:55:32 +0530 Subject: [Haskell-beginners] Haskell -> JavaScript -> nodejs In-Reply-To: <558538DA.8030002@vlkk.cz> References: <558513E4.2070600@vlkk.cz> <558538DA.8030002@vlkk.cz> Message-ID: Better try on the cafe. cc-ing. On 20 June 2015 at 15:26, Martin Vlk wrote: > I made some progress - in order for Haskell modules to work with ghcjs > you need to use cabal with the --ghcjs flag to install them. > > Martin > > Martin Vlk: > > Hi, > > I can successfully compile a basic Hello World into JavaScript with > > ghcjs and run it with nodejs. > > But what I ultimately need to do is write a nodejs module in Haskell and > > compile down to JavaScript with ghcjs. I need to be able to require > > other nodejs modules as well. > > > > Could somebody point me in the right direction? E.g. what approach and > > libraries to use... > > > > I have tried a simple thing with jsaddle/lens, but when I try to compile > > with ghcjs it is not finding the imported modules, even though when > > compiling with ghc it does find them (they are installed using cabal). > > > > Many Thanks > > Martin > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- Regards Sumit Sahrawat -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at beyermatthias.de Sat Jun 20 19:54:27 2015 From: mail at beyermatthias.de (Matthias Beyer) Date: Sat, 20 Jun 2015 21:54:27 +0200 Subject: [Haskell-beginners] Help - I'm completely lost with building a really simple app with Snap and Groundhog Message-ID: <20150620195427.GC5689@lucy.3gs> Hi, I am learning Haskell by trying to implement a really simple CRUD like web app with Snap and Groundhog - and I'm completely lost, cannot get it to work. The relevant code is here: https://github.com/matthiasbeyer/rate.hs/tree/restart_clean What the app should be able to do: - CRUD Categories, where a category can have several subcategories or Ratings - CRUD Ratings, where a rating has a title, a description and, of course, a rating (something like a number from 0-10) That's it. Backend should be postgresql, frontend should contain a list of all categories with all ratings (a simple tree) and each rating should have its own page where the description is listed. So, I guess, this is not really complex or anything, but I'm completely list with both integrating groundhog and heist, the former beeing my current step. Can someone digg into my code and tell me what I'm doing wrong? Or maybe even provide a _good_ tutorial for me? Or even be my mentor for this? Would be really nice! Good night, Haskell community! -- Mit freundlichen Gr??en, Kind regards, Matthias Beyer Proudly sent with mutt. Happily signed with gnupg. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From peter at harpending.org Sat Jun 20 23:50:49 2015 From: peter at harpending.org (Peter Harpending) Date: Sat, 20 Jun 2015 17:50:49 -0600 Subject: [Haskell-beginners] Help - I'm completely lost with building a really simple app with Snap and Groundhog In-Reply-To: <20150620195427.GC5689@lucy.3gs> References: <20150620195427.GC5689@lucy.3gs> Message-ID: <20150620235049.GA23212@harpending.org> On Sat, Jun 20, 2015 at 09:54:27PM +0200, Matthias Beyer wrote: > I am learning Haskell by trying to implement a really simple CRUD like > web app with Snap and Groundhog - and I'm completely lost, cannot get > it to work. Since you seem to know what all of those things are, I'm going to assume you have some background in imperative programming. This assumption is backed by your GitHub history. I'm guessing, after the initial few languages, with most programming languages you've encountered thus far, you can learn a new one in a week or two. Haskell isn't like other languages. It requires a fundamentally different manner of thinking about your program. It's like learning to program all over again. It is worth it, I promise. As for learning Haskell, Chris Allen's tutorial has links to resources covering everything under the sun: . Now, regarding your actual question: what's wrong with the code you have posted? 1. First of all, your dependencies are way too strict in your cabal file. In fact, most of them conflict. I couldn't even run `cabal install`. If you want to make sure the packages play together nicely, you should use Stackage . 2. Nobody uses old versions of base anymore. You don't need that old-base stuff. 3. Your cabal file needs a default-language field. 4. Snap is a bit labor-intensive. Yesod is much more well-suited for non-trivial web applications. Once I cleaned up the cabal file, I was able to get the standard Hello, World Snap application running on localhost. I forked your repository on GitHub. You can see the changes I made here: . Note that I am using GHC 7.10, which is the latest version. You might be on an old version of GHC, in which case, you should do the following: rm cabal.config cabal install cabal freeze To run the application, I just used `cabal run`. Peter Harpending -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From peter at harpending.org Sat Jun 20 23:53:24 2015 From: peter at harpending.org (Peter Harpending) Date: Sat, 20 Jun 2015 17:53:24 -0600 Subject: [Haskell-beginners] Help - I'm completely lost with building a really simple app with Snap and Groundhog In-Reply-To: <20150620235049.GA23212@harpending.org> References: <20150620195427.GC5689@lucy.3gs> <20150620235049.GA23212@harpending.org> Message-ID: <20150620235324.GB23212@harpending.org> And I just realized I based all of this off of what was in the master branch. Oh well. See if it's helpful anyway. Peter Harpending On Sat, Jun 20, 2015 at 05:50:49PM -0600, Peter Harpending wrote: > On Sat, Jun 20, 2015 at 09:54:27PM +0200, Matthias Beyer wrote: > > I am learning Haskell by trying to implement a really simple CRUD like > > web app with Snap and Groundhog - and I'm completely lost, cannot get > > it to work. > > Since you seem to know what all of those things are, I'm going to assume > you have some background in imperative programming. This assumption is > backed by your GitHub history. > > I'm guessing, after the initial few languages, with most programming > languages you've encountered thus far, you can learn a new one in a week > or two. > > Haskell isn't like other languages. It requires a fundamentally > different manner of thinking about your program. It's like learning to > program all over again. It is worth it, I promise. > > As for learning Haskell, Chris Allen's tutorial has links to resources > covering everything under the sun: > . > > Now, regarding your actual question: what's wrong with the code you have > posted? > > 1. First of all, your dependencies are way too strict in your cabal > file. In fact, most of them conflict. I couldn't even run `cabal > install`. > > If you want to make sure the packages play together nicely, you > should use Stackage . > > 2. Nobody uses old versions of base anymore. You don't need that > old-base stuff. > > 3. Your cabal file needs a default-language field. > > 4. Snap is a bit labor-intensive. Yesod is > much more well-suited for non-trivial web applications. > > Once I cleaned up the cabal file, I was able to get the standard Hello, > World Snap application running on localhost. > > I forked your repository on GitHub. You can see the changes I made here: > . Note > that I am using GHC 7.10, which is the latest version. You might be on > an old version of GHC, in which case, you should do the following: > > rm cabal.config > cabal install > cabal freeze > > To run the application, I just used `cabal run`. > > Peter Harpending -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From amindfv at gmail.com Sun Jun 21 00:09:37 2015 From: amindfv at gmail.com (amindfv at gmail.com) Date: Sat, 20 Jun 2015 17:09:37 -0700 Subject: [Haskell-beginners] Help - I'm completely lost with building a really simple app with Snap and Groundhog In-Reply-To: <20150620235049.GA23212@harpending.org> References: <20150620195427.GC5689@lucy.3gs> <20150620235049.GA23212@harpending.org> Message-ID: El Jun 20, 2015, a las 16:50, Peter Harpending escribi?: > On Sat, Jun 20, 2015 at 09:54:27PM +0200, Matthias Beyer wrote: >> I am learning Haskell by trying to implement a really simple CRUD like >> web app with Snap and Groundhog - and I'm completely lost, cannot get >> it to work. > > Since you seem to know what all of those things are, I'm going to assume > you have some background in imperative programming. This assumption is > backed by your GitHub history. > > I'm guessing, after the initial few languages, with most programming > languages you've encountered thus far, you can learn a new one in a week > or two. > > Haskell isn't like other languages. It requires a fundamentally > different manner of thinking about your program. It's like learning to > program all over again. It is worth it, I promise. > > As for learning Haskell, Chris Allen's tutorial has links to resources > covering everything under the sun: > . > > Now, regarding your actual question: what's wrong with the code you have > posted? > > 1. First of all, your dependencies are way too strict in your cabal > file. In fact, most of them conflict. I couldn't even run `cabal > install`. > > If you want to make sure the packages play together nicely, you > should use Stackage . > > 2. Nobody uses old versions of base anymore. You don't need that > old-base stuff. > > 3. Your cabal file needs a default-language field. > > 4. Snap is a bit labor-intensive. Yesod is > much more well-suited for non-trivial web applications. > [[citation needed]] Snap is used for lots of large production sites, and I don't think anyone would claim it's more complex for a beginner. Not starting a flamewar, just disputung that one is worse. > Once I cleaned up the cabal file, I was able to get the standard Hello, > World Snap application running on localhost. > > I forked your repository on GitHub. You can see the changes I made here: > . Note > that I am using GHC 7.10, which is the latest version. You might be on > an old version of GHC, in which case, you should do the following: > > rm cabal.config > cabal install > cabal freeze > > To run the application, I just used `cabal run`. > > Peter Harpending > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From bdezonia at gmail.com Sun Jun 21 01:29:30 2015 From: bdezonia at gmail.com (Barry DeZonia) Date: Sat, 20 Jun 2015 20:29:30 -0500 Subject: [Haskell-beginners] Reading binary data into numeric types Message-ID: Hello, I need to write some code that will read binary data from a file into various types defined in Data.Int, Data.Word, and the floating types. I am looking to make functions with signatures like Handle->IO Word16 and Handle->IO Int32 and Handle->IO Float and others similarly defined. One complication I am running into is that the data is stored in big endian byte order. So my functions need to be flexible with byte ordering (and I need to determine the endian ordering of the current platform). Anyhow I'm pretty much a newbie and don't know how to do this. For a float in an imperitive language I might read 4 bytes, possibly reorder them based on platform endian value, and interpret the bytes as a float via a ptr. Would the process be similar in Haskell? Pointers appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sun Jun 21 01:32:43 2015 From: allbery.b at gmail.com (Brandon Allbery) Date: Sat, 20 Jun 2015 21:32:43 -0400 Subject: [Haskell-beginners] Reading binary data into numeric types In-Reply-To: References: Message-ID: On Sat, Jun 20, 2015 at 9:29 PM, Barry DeZonia wrote: > I need to write some code that will read binary data from a file into > various types defined in Data.Int, Data.Word, and the floating types. I am > looking to make functions with signatures like Handle->IO Word16 and > Handle->IO Int32 and Handle->IO Float and others similarly defined. One > complication I am running into is that the data is stored in big endian > byte > Hopefully you don't have some requirement to reinvent this wheel; the binary package already provides it, including support for endianness. http://hackage.haskell.org/package/binary -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at beyermatthias.de Sun Jun 21 09:23:01 2015 From: mail at beyermatthias.de (Matthias Beyer) Date: Sun, 21 Jun 2015 11:23:01 +0200 Subject: [Haskell-beginners] Help - I'm completely lost with building a really simple app with Snap and Groundhog In-Reply-To: <20150620235324.GB23212@harpending.org> References: <20150620195427.GC5689@lucy.3gs> <20150620235049.GA23212@harpending.org> <20150620235324.GB23212@harpending.org> Message-ID: <20150621092301.GE5689@lucy.3gs> Hi, thanks a lot for your reply. Answer is inline: On 20-06-2015 17:53:24, Peter Harpending wrote: > And I just realized I based all of this off of what was in the master > branch. Oh well. See if it's helpful anyway. > nvm, I'll read through it and apply onto my branch, thanks! > > On Sat, Jun 20, 2015 at 05:50:49PM -0600, Peter Harpending wrote: > > On Sat, Jun 20, 2015 at 09:54:27PM +0200, Matthias Beyer wrote: > > > I am learning Haskell by trying to implement a really simple CRUD like > > > web app with Snap and Groundhog - and I'm completely lost, cannot get > > > it to work. > > > > Since you seem to know what all of those things are, I'm going to assume > > you have some background in imperative programming. This assumption is > > backed by your GitHub history. > > > > I'm guessing, after the initial few languages, with most programming > > languages you've encountered thus far, you can learn a new one in a week > > or two. > > > > Haskell isn't like other languages. It requires a fundamentally > > different manner of thinking about your program. It's like learning to > > program all over again. It is worth it, I promise. There is no need to convince me! I already lost my soul to FP and Haskell! I know the concept is completely different from what I've learned so far, and I know I have to re-learn things, but I also know that it's worth it! > > > > As for learning Haskell, Chris Allen's tutorial has links to resources > > covering everything under the sun: > > . > > Thanks for reminding me of this! > > Now, regarding your actual question: what's wrong with the code you have > > posted? My problem was that I didn't get groundhog to be integrated in my web app. I already solved this, as you can see here: https://github.com/matthiasbeyer/rate.hs/tree/restart_clean But still, I am not able to get my migrations running. > > > > 1. First of all, your dependencies are way too strict in your cabal > > file. In fact, most of them conflict. I couldn't even run `cabal > > install`. > > Hm. I can run `cabal configure` without problems. I did not run `cabal install`, though, as I'm on nixos and it won't work anyways! > > If you want to make sure the packages play together nicely, you > > should use Stackage . > > I'm using the cabal packages from nixos (haskellngPackages set). I'm not sure how to know whether they play nicely together or not... > > 2. Nobody uses old versions of base anymore. You don't need that > > old-base stuff. Ok, will remove it. It is what `snap init` gave me, as far as I can remember! > > > > 3. Your cabal file needs a default-language field. Will add that. > > > > 4. Snap is a bit labor-intensive. Yesod is > > much more well-suited for non-trivial web applications. I won't switch to yesod. Yesod is far more complex as far as I can tell. It might be well suited for the app I want to write after this one, which will be much more complex, but I guess I will still stick with Snap as it is (IMHO) easier to learn. Maybe you can convince me here. > > > > Once I cleaned up the cabal file, I was able to get the standard Hello, > > World Snap application running on localhost. > > > > I forked your repository on GitHub. You can see the changes I made here: > > . Note > > that I am using GHC 7.10, which is the latest version. You might be on > > an old version of GHC, in which case, you should do the following: I'm on GHC 7.10.1, thanks! NixOS ships the latest, thankfully! :-) -- Mit freundlichen Gr??en, Kind regards, Matthias Beyer Proudly sent with mutt. Happily signed with gnupg. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From martin at vlkk.cz Sun Jun 21 20:02:11 2015 From: martin at vlkk.cz (Martin Vlk) Date: Sun, 21 Jun 2015 20:02:11 +0000 Subject: [Haskell-beginners] Haskell -> JavaScript -> nodejs In-Reply-To: References: <558513E4.2070600@vlkk.cz> <558538DA.8030002@vlkk.cz> Message-ID: <55871843.2080002@vlkk.cz> Thanks, in the end I was able to figure it out, here is the code: (https://github.com/martinvlk/ghcjs-node-minimal) {-# LANGUAGE JavaScriptFFI, OverloadedStrings #-} module Main (main) where import GHCJS.Types import GHCJS.Foreign foreign import javascript unsafe "require($1)" require :: JSString -> IO (JSRef a) foreign import javascript unsafe "$1.hostname()" hostname :: JSRef a -> IO JSString main :: IO () main = require "os" >>= hostname >>= \h -> putStrLn $ "Our hostname is '" ++ (fromJSString h) ++ "'" Martin Sumit Sahrawat, Maths & Computing, IIT (BHU): > Better try on the cafe. cc-ing. > > On 20 June 2015 at 15:26, Martin Vlk wrote: > >> I made some progress - in order for Haskell modules to work with ghcjs >> you need to use cabal with the --ghcjs flag to install them. >> >> Martin >> >> Martin Vlk: >>> Hi, >>> I can successfully compile a basic Hello World into JavaScript with >>> ghcjs and run it with nodejs. >>> But what I ultimately need to do is write a nodejs module in Haskell and >>> compile down to JavaScript with ghcjs. I need to be able to require >>> other nodejs modules as well. >>> >>> Could somebody point me in the right direction? E.g. what approach and >>> libraries to use... >>> >>> I have tried a simple thing with jsaddle/lens, but when I try to compile >>> with ghcjs it is not finding the imported modules, even though when >>> compiling with ghc it does find them (they are installed using cabal). >>> >>> Many Thanks >>> Martin >>> >> _______________________________________________ >> 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 matt.williams45.mw at gmail.com Mon Jun 22 10:29:40 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Mon, 22 Jun 2015 10:29:40 +0000 Subject: [Haskell-beginners] Structural restrictions in type constructor Message-ID: Dear All, I wonder if/ how this is possible? I have a constructor which takes 2 pairs of type t). However, I want to ensure that the pairs are matched: MyP = MyP (t, t) (t, t) But where the first pair contains the same elements as the second, but reversed in order. Any help much appreciated. BW, Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at vlkk.cz Mon Jun 22 10:49:05 2015 From: martin at vlkk.cz (Martin Vlk) Date: Mon, 22 Jun 2015 10:49:05 +0000 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: <5587E821.2060602@vlkk.cz> I would think that it is not possible to use types to constrain the values of data. I.e. type signature can be only used to constraint types, not values. But I am a beginner myself, so see if someone more experienced can shed light here. Martin Matt Williams: > Dear All, > > I wonder if/ how this is possible? > > I have a constructor which takes 2 pairs of type t). > > However, I want to ensure that the pairs are matched: > > MyP = MyP (t, t) (t, t) > > But where the first pair contains the same elements as the second, but > reversed in order. > > Any help much appreciated. > > BW, > Matt > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > From imantc at gmail.com Mon Jun 22 11:29:36 2015 From: imantc at gmail.com (Imants Cekusins) Date: Mon, 22 Jun 2015 13:29:36 +0200 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: <5587E821.2060602@vlkk.cz> References: <5587E821.2060602@vlkk.cz> Message-ID: we could use pattern matched constructor: module PairsMatched where data MyP t = MyP (t,t)(t,t) deriving Show myP_ctor:: Eq t => (t,t)->(t,t)->MyP t myP_ctor (a1,a2) (a3,a4) | a1 == a4 && a2 == a3 = MyP (a1,a2) (a3,a4) | otherwise = error "mismatched pairs" From martin at vlkk.cz Mon Jun 22 11:34:40 2015 From: martin at vlkk.cz (Martin Vlk) Date: Mon, 22 Jun 2015 11:34:40 +0000 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: <5587E821.2060602@vlkk.cz> Message-ID: <5587F2D0.4090100@vlkk.cz> But this is checking the values in the implementation, not a type level build time guarantee, isn't it? M Imants Cekusins: > we could use pattern matched constructor: > > module PairsMatched where > > data MyP t = MyP (t,t)(t,t) deriving Show > > > myP_ctor:: Eq t => (t,t)->(t,t)->MyP t > myP_ctor (a1,a2) (a3,a4) > | a1 == a4 && a2 == a3 = MyP (a1,a2) (a3,a4) > | otherwise = error "mismatched pairs" > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > From imantc at gmail.com Mon Jun 22 11:36:03 2015 From: imantc at gmail.com (Imants Cekusins) Date: Mon, 22 Jun 2015 13:36:03 +0200 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: <5587F2D0.4090100@vlkk.cz> References: <5587E821.2060602@vlkk.cz> <5587F2D0.4090100@vlkk.cz> Message-ID: > But this is checking the values in the implementation, not a type level build time guarantee, isn't it? yep, correct. Could be caught by unit tests though :-P From objitsu at gmail.com Mon Jun 22 13:51:19 2015 From: objitsu at gmail.com (emacstheviking) Date: Mon, 22 Jun 2015 14:51:19 +0100 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: <5587E821.2060602@vlkk.cz> <5587F2D0.4090100@vlkk.cz> Message-ID: It *could* be done and might already have been done... I seem to recall a few months back somebody asked for a similar feature using one of the vector libraries, to limit one of the input vectors to a fixed length? You'd have to dig through the list archives though... On 22 June 2015 at 12:36, Imants Cekusins wrote: > > But this is checking the values in the implementation, not a type level > build time guarantee, isn't it? > > yep, correct. Could be caught by unit tests though :-P > _______________________________________________ > 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 matt.williams45.mw at gmail.com Mon Jun 22 14:00:25 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Mon, 22 Jun 2015 15:00:25 +0100 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: <5587E821.2060602@vlkk.cz> <5587F2D0.4090100@vlkk.cz> Message-ID: OK, I think this is clearly well beyond my level! Will insert some manual checking. Thanks, Matt On 22 June 2015 at 14:51, emacstheviking wrote: > It *could* be done and might already have been done... I seem to recall a > few months back somebody asked for a similar feature using one of the > vector libraries, to limit one of the input vectors to a fixed length? > > You'd have to dig through the list archives though... > > On 22 June 2015 at 12:36, Imants Cekusins wrote: > >> > But this is checking the values in the implementation, not a type level >> build time guarantee, isn't it? >> >> yep, correct. Could be caught by unit tests though :-P >> _______________________________________________ >> 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 janus_1118 at outlook.com Mon Jun 22 16:08:09 2015 From: janus_1118 at outlook.com (Bruno Sotelo Klinec) Date: Mon, 22 Jun 2015 13:08:09 -0300 Subject: [Haskell-beginners] Function problem Message-ID: Hi there! I was hoping you could help me a bit here with making a function. I am asked to write functions to make a mini robot game, which uses these data and types: data Program = Move Direction Program |Radar (Robot -> Point) Program |Shoot Point Program |Surrender data Direction = N|S|E|O type Point = (Int,Int) data Robot = R1|R2 And then I have to write functions like this: prog1::Program prog1 = Move E $ Radar R1 (2,4) $ Radar R2 (5,6) $ Shoot (5,7) prog1 My problem is the function adjust::Direction->Program->Program that takes one direction and a program and moves every shot in that program one unit in the given direction. I can't figure out how to do this, I would really appreciate you could help me, thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: From toad3k at gmail.com Mon Jun 22 16:35:05 2015 From: toad3k at gmail.com (David McBride) Date: Mon, 22 Jun 2015 12:35:05 -0400 Subject: [Haskell-beginners] Function problem In-Reply-To: References: Message-ID: If you pass a program into this instruction, if it sees a shoot, it will modify it slightly, if it is some other instruction, it will simply leave the instruction unchanged, and then call itself on the rest of the program. Use pattern matching to do this (untested code): adjust :: Direction -> Program -> Direction adjust dir (Shoot point next) = Shoot (adjustPoint dir point) $ adjust dir next where adjustPoint :: Dir -> Point -> Point adjustPoint N (x,y) = (x, y+1) adjustPoint ... = ... adjust dir (Move d next) = Move d $ adjust dir next adjust ... = ... adjust _ (Surrender) = Surrender On Mon, Jun 22, 2015 at 12:08 PM, Bruno Sotelo Klinec < janus_1118 at outlook.com> wrote: > Hi there! I was hoping you could help me a bit here with making a > function. I am asked to write functions to make a mini robot game, which > uses these data and types: > > data Program = Move Direction Program > |Radar (Robot -> Point) Program > |Shoot Point Program > |Surrender > data Direction = N|S|E|O > type Point = (Int,Int) > data Robot = R1|R2 > > And then I have to write functions like this: > prog1::Program > prog1 = Move E $ Radar R1 (2,4) $ Radar R2 (5,6) $ Shoot (5,7) prog1 > > My problem is the function adjust::Direction->Program->Program that takes > one direction and a program and moves every shot in that program one unit > in the given direction. I can't figure out how to do this, I would really > appreciate you could help me, thanks! > > _______________________________________________ > 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 rein.henrichs at gmail.com Mon Jun 22 19:09:36 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Mon, 22 Jun 2015 19:09:36 +0000 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: <5587E821.2060602@vlkk.cz> <5587F2D0.4090100@vlkk.cz> Message-ID: You can't do this at the type level in Haskell. On Mon, Jun 22, 2015 at 7:00 AM Matt Williams wrote: > OK, I think this is clearly well beyond my level! > > Will insert some manual checking. > > Thanks, > Matt > > On 22 June 2015 at 14:51, emacstheviking wrote: > >> It *could* be done and might already have been done... I seem to recall a >> few months back somebody asked for a similar feature using one of the >> vector libraries, to limit one of the input vectors to a fixed length? >> >> You'd have to dig through the list archives though... >> >> On 22 June 2015 at 12:36, Imants Cekusins wrote: >> >>> > But this is checking the values in the implementation, not a type level >>> build time guarantee, isn't it? >>> >>> yep, correct. Could be caught by unit tests though :-P >>> _______________________________________________ >>> 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 >> >> > _______________________________________________ > 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 petr.vapenka at gmail.com Mon Jun 22 19:18:02 2015 From: petr.vapenka at gmail.com (=?UTF-8?Q?Petr_V=C3=A1penka?=) Date: Mon, 22 Jun 2015 21:18:02 +0200 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: <5587E821.2060602@vlkk.cz> <5587F2D0.4090100@vlkk.cz> Message-ID: Maybe not exactly what you need but this was for me a kind of eye-opener with regard to type system: https://github.com/leonidas/codeblog/blob/master/2013/2013-02-19-typesafe-tictactoe.md On Mon, Jun 22, 2015 at 9:09 PM, Rein Henrichs wrote: > You can't do this at the type level in Haskell. > > On Mon, Jun 22, 2015 at 7:00 AM Matt Williams < > matt.williams45.mw at gmail.com> wrote: > >> OK, I think this is clearly well beyond my level! >> >> Will insert some manual checking. >> >> Thanks, >> Matt >> >> On 22 June 2015 at 14:51, emacstheviking wrote: >> >>> It *could* be done and might already have been done... I seem to recall >>> a few months back somebody asked for a similar feature using one of the >>> vector libraries, to limit one of the input vectors to a fixed length? >>> >>> You'd have to dig through the list archives though... >>> >>> On 22 June 2015 at 12:36, Imants Cekusins wrote: >>> >>>> > But this is checking the values in the implementation, not a type >>>> level >>>> build time guarantee, isn't it? >>>> >>>> yep, correct. Could be caught by unit tests though :-P >>>> _______________________________________________ >>>> 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 >>> >>> >> _______________________________________________ >> 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 janus_1118 at outlook.com Tue Jun 23 00:25:36 2015 From: janus_1118 at outlook.com (Bruno Sotelo Klinec) Date: Mon, 22 Jun 2015 21:25:36 -0300 Subject: [Haskell-beginners] Function problem In-Reply-To: References: , Message-ID: Thanks! I thought pattern matching or case analysis wouldn't work well with functions -------------- next part -------------- An HTML attachment was scrubbed... URL: From k-bx at k-bx.com Tue Jun 23 12:54:07 2015 From: k-bx at k-bx.com (Kostiantyn Rybnikov) Date: Tue, 23 Jun 2015 15:54:07 +0300 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: Hi Matt. I don't know how bad is this, but here's what I came up with. In order to be able to ask types to make sure something about values (their equality), you might want to create a type, which contains a value in its type-parameter, and then ask that types are equal if you want some equality property in datatype. Here's an example: {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneDeriving #-} module Main where import GHC.TypeLits newtype TypeValInt (n::Nat) = TypeValInt Int deriving (Show) one :: TypeValInt 1 one = TypeValInt 1 two :: TypeValInt 2 two = TypeValInt 2 data MyP a b = MyP (TypeValInt a, TypeValInt b) (TypeValInt b, TypeValInt a) deriving (Show) main :: IO () main = do putStrLn "Hello!" print (MyP (one, two) (two, one)) -- | this will error: -- print (MyP (one, two) (one, one)) print (MyPGen (one, two) (two, one)) -- | this will error: -- print (MyPGen (one, two) (one, one)) class TypeVal (g :: a -> *) instance TypeVal TypeValInt data MyPGen a b = forall g. (TypeVal g, Show (g a), Show (g b)) => MyPGen (g a, g b) (g b, g a) deriving instance Show (MyPGen a b) On Mon, Jun 22, 2015 at 1:29 PM, Matt Williams wrote: > Dear All, > > I wonder if/ how this is possible? > > I have a constructor which takes 2 pairs of type t). > > However, I want to ensure that the pairs are matched: > > MyP = MyP (t, t) (t, t) > > But where the first pair contains the same elements as the second, but > reversed in order. > > Any help much appreciated. > > BW, > Matt > > _______________________________________________ > 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 imantc at gmail.com Tue Jun 23 14:05:11 2015 From: imantc at gmail.com (Imants Cekusins) Date: Tue, 23 Jun 2015 16:05:11 +0200 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: On 23 June 2015 at 14:54, Kostiantyn Rybnikov wrote: > Hi Matt. I don't know how bad is this, but here's what I came up with. ... this modified for IO version accepts any input, including that which should have caused error: or did I do something wrong? {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneDeriving #-} module PairsMatchedKR where import GHC.TypeLits data TypeValInt (n::Nat) = TypeValInt Int deriving (Show) one :: TypeValInt 1 one = TypeValInt 1 two :: TypeValInt 2 two = TypeValInt 2 data MyP a b = MyP (TypeValInt a, TypeValInt b) (TypeValInt b, TypeValInt a) deriving (Show) main :: IO () main = do putStrLn "Hello!" x1 <- getLine x2 <- getLine x3 <- getLine x4 <- getLine print (MyP (tvi x1, tvi x2) (tvi x3, tvi x4)) class TypeVal (g :: a -> *) instance TypeVal TypeValInt data MyPGen a b = forall g. (TypeVal g, Show (g a), Show (g b)) => MyPGen (g a, g b) (g b, g a) deriving instance Show (MyPGen a b) tvi:: String -> TypeValInt (n::Nat) tvi = TypeValInt . read From k-bx at k-bx.com Tue Jun 23 14:33:06 2015 From: k-bx at k-bx.com (Kostiantyn Rybnikov) Date: Tue, 23 Jun 2015 17:33:06 +0300 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: Imants, You are right. The problem is not in IO here, it's that if you have access to data-constructor, you can do things like: six :: TypeValInt 6 six = TypeValInt 5 Initially, I was making an assumption that you won't be using a data-constructor. After thinking about it a bit, I should note that my code isn't much different from just using a "smart constructor" approach, e.g. hiding a real MyP constructor, and instead providing a function: mkMyP (a, b) = MyP (a, b) (b, a) and exporting only this function. This would make sure all your users only create a valid set of data. On Tue, Jun 23, 2015 at 5:05 PM, Imants Cekusins wrote: > On 23 June 2015 at 14:54, Kostiantyn Rybnikov wrote: > > Hi Matt. I don't know how bad is this, but here's what I came up with. > ... > > this modified for IO version accepts any input, including that which > should have caused error: > > or did I do something wrong? > > > {-# LANGUAGE DataKinds #-} > {-# LANGUAGE KindSignatures #-} > {-# LANGUAGE ExistentialQuantification #-} > {-# LANGUAGE PolyKinds #-} > {-# LANGUAGE StandaloneDeriving #-} > > module PairsMatchedKR where > > import GHC.TypeLits > > data TypeValInt (n::Nat) = TypeValInt Int > deriving (Show) > > one :: TypeValInt 1 > one = TypeValInt 1 > > two :: TypeValInt 2 > two = TypeValInt 2 > > data MyP a b = MyP (TypeValInt a, TypeValInt b) (TypeValInt b, TypeValInt > a) > deriving (Show) > > main :: IO () > main = do > putStrLn "Hello!" > x1 <- getLine > x2 <- getLine > x3 <- getLine > x4 <- getLine > > print (MyP (tvi x1, tvi x2) (tvi x3, tvi x4)) > > class TypeVal (g :: a -> *) > instance TypeVal TypeValInt > > data MyPGen a b = forall g. (TypeVal g, Show (g a), Show (g b)) > => MyPGen (g a, g b) (g b, g a) > deriving instance Show (MyPGen a b) > > > tvi:: String -> TypeValInt (n::Nat) > tvi = TypeValInt . read > _______________________________________________ > 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 alanbuxton at gmail.com Tue Jun 23 14:48:18 2015 From: alanbuxton at gmail.com (Alan Buxton) Date: Tue, 23 Jun 2015 15:48:18 +0100 Subject: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" Message-ID: <01c301d0adc3$a59137d0$f0b3a770$@gmail.com> Hi I've recently set up a new Haskell working environment on Ubuntu 14.04. I installed the Ubuntu packaged version of Haskell platform. My problem is that I can't now get ghc-mod check to work if there is a cabal file in the current directory. I am using: * ghc-mod 5.2.1.2 compiled by GHC 7.6.3 * cabal 1.16.0.2 See below an extract of trying to run ghc-mod check in a directory that was empty until I just ran cabal init in it: ~/tmp-ghc-mod$ ls Setup.hs tmp-ghc-mod.cabal ~/tmp-ghc-mod$ ghc-mod check Setup.hs Setup.hs:1:1:Could not find module `Prelude'It is a member of the hidden package `base'.Perhaps you need to add `base' to the build-depends in your .cabal file.It is a member of the hidden package `haskell98-2.0.0.2'.Perhaps you need to add `haskell98' to the build-depends in your .cabal file.It is a member of the hidden package `haskell2010-1.1.1.0'.Perhaps you need to add `haskell2010' to the build-depends in your .cabal file.Use -v to see a list of the files searched for. ~/tmp-ghc-mod$ mv tmp-ghc-mod.cabal tmp-ghc-mod.cabal.NOT ~/tmp-ghc-mod$ ls dist Setup.hs tmp-ghc-mod.cabal.NOT ~/tmp-ghc-mod$ ghc-mod check Setup.hs Setup.hs:2:1:Warning: Top-level binding with no type signature: main :: IO () ~/tmp-ghc-mod$ So. ghc-mod behaves as expected when there is no cabal file, but doesn't behave as expected if there is a cabal file. My google fu isn't helping me out on this: the only issues I have seen are to do with a change in format of the cabal file in newer versions of cabal. Any ideas? Thanks Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From timmelzer at gmail.com Tue Jun 23 16:49:16 2015 From: timmelzer at gmail.com (Norbert Melzer) Date: Tue, 23 Jun 2015 16:49:16 +0000 Subject: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" In-Reply-To: <01c301d0adc3$a59137d0$f0b3a770$@gmail.com> References: <01c301d0adc3$a59137d0$f0b3a770$@gmail.com> Message-ID: Just add base as dependency in the version constraints matching that base that is delivered with your version of GHC. Alan Buxton schrieb am Di., 23.06.2015, 16:48: > Hi > > > > I?ve recently set up a new Haskell working environment on Ubuntu 14.04. I > installed the Ubuntu packaged version of Haskell platform. > > > > My problem is that I can?t now get ghc-mod check to work if there is a > cabal file in the current directory. > > > > > > I am using: > > ? ghc-mod 5.2.1.2 compiled by GHC 7.6.3 > > ? cabal 1.16.0.2 > > > > See below an extract of trying to run ghc-mod check in a directory that > was empty until I just ran cabal init in it: > > > > ~/tmp-ghc-mod$ ls > > Setup.hs tmp-ghc-mod.cabal > > ~/tmp-ghc-mod$ ghc-mod check Setup.hs > > Setup.hs:1:1:Could not find module `Prelude'It is a member of the hidden > package `base'.Perhaps you need to add `base' to the build-depends in your > .cabal file.It is a member of the hidden package > `haskell98-2.0.0.2'.Perhaps you need to add `haskell98' to the > build-depends in your .cabal file.It is a member of the hidden package > `haskell2010-1.1.1.0'.Perhaps you need to add `haskell2010' to the > build-depends in your .cabal file.Use -v to see a list of the files > searched for. > > ~/tmp-ghc-mod$ mv tmp-ghc-mod.cabal tmp-ghc-mod.cabal.NOT > > ~/tmp-ghc-mod$ ls > > dist Setup.hs tmp-ghc-mod.cabal.NOT > > ~/tmp-ghc-mod$ ghc-mod check Setup.hs > > Setup.hs:2:1:Warning: Top-level binding with no type signature: main :: IO > () > > ~/tmp-ghc-mod$ > > > > So? ghc-mod behaves as expected when there is no cabal file, but doesn?t > behave as expected if there is a cabal file. > > > > My google fu isn?t helping me out on this: the only issues I have seen are > to do with a change in format of the cabal file in newer versions of cabal. > > > > Any ideas? > > > > Thanks > > Alan > > > > > _______________________________________________ > 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 alanbuxton at gmail.com Tue Jun 23 17:47:05 2015 From: alanbuxton at gmail.com (Alan Buxton) Date: Tue, 23 Jun 2015 18:47:05 +0100 Subject: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" In-Reply-To: References: <01c301d0adc3$a59137d0$f0b3a770$@gmail.com> Message-ID: <01e201d0addc$9f64d420$de2e7c60$@gmail.com> Thanks for the suggestions: Imants: There is library build-depends: base ==4.6.* (The cabal file was generated by cabal init and so I would hope it's legit :)) I installed Haskell on my Ubuntu just by doing sudo apt-get install haskell-platform. Interestingly, if I do use ghc-mod on a real file with some errors in I get unnecessarily verbose error messages similar to described here: http://mail.haskell.org/pipermail/beginners/2015-February/014573.html I wonder if the issues are related somehow? Norbert: I?m not sure what exactly you are suggesting but if I even take the version constraint out of the cabal file so I have build-depends: base (without any version specified) then I get the same issue. From: Beginners [mailto:beginners-bounces at haskell.org] On Behalf Of Norbert Melzer Sent: 23 June 2015 17:49 To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell Subject: Re: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" Just add base as dependency in the version constraints matching that base that is delivered with your version of GHC. Alan Buxton > schrieb am Di., 23.06.2015, 16:48: Hi I?ve recently set up a new Haskell working environment on Ubuntu 14.04. I installed the Ubuntu packaged version of Haskell platform. My problem is that I can?t now get ghc-mod check to work if there is a cabal file in the current directory. I am using: * ghc-mod 5.2.1.2 compiled by GHC 7.6.3 * cabal 1.16.0.2 See below an extract of trying to run ghc-mod check in a directory that was empty until I just ran cabal init in it: ~/tmp-ghc-mod$ ls Setup.hs tmp-ghc-mod.cabal ~/tmp-ghc-mod$ ghc-mod check Setup.hs Setup.hs:1:1:Could not find module `Prelude'It is a member of the hidden package `base'.Perhaps you need to add `base' to the build-depends in your .cabal file.It is a member of the hidden package `haskell98-2.0.0.2'.Perhaps you need to add `haskell98' to the build-depends in your .cabal file.It is a member of the hidden package `haskell2010-1.1.1.0'.Perhaps you need to add `haskell2010' to the build-depends in your .cabal file.Use -v to see a list of the files searched for. ~/tmp-ghc-mod$ mv tmp-ghc-mod.cabal tmp-ghc-mod.cabal.NOT ~/tmp-ghc-mod$ ls dist Setup.hs tmp-ghc-mod.cabal.NOT ~/tmp-ghc-mod$ ghc-mod check Setup.hs Setup.hs:2:1:Warning: Top-level binding with no type signature: main :: IO () ~/tmp-ghc-mod$ So? ghc-mod behaves as expected when there is no cabal file, but doesn?t behave as expected if there is a cabal file. My google fu isn?t helping me out on this: the only issues I have seen are to do with a change in format of the cabal file in newer versions of cabal. Any ideas? Thanks Alan _______________________________________________ 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 matt.williams45.mw at gmail.com Tue Jun 23 19:21:03 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Tue, 23 Jun 2015 19:21:03 +0000 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: Dear All, This has reminded me that perhaps there is an easier way. I have a Map, whose elements are indexed by a subset of their structure. I.e. if we have MyType = MyType I T T O E Where I T O and E are types defined elsewhere. The Map the indexes elements of type MyType by a pair, (T, T). I want to be able to index by a pair, independent of order. I had thought about indexing by a pair of pairs, where the elemtns could be the same but reversed. However, the alternative might be to index by a pair, but define that pair as a type, and alter its Eq => definition: MyPair = (T, T) where (t, t') == (t', t) -- I know this syntax is wrong I could then use that as the index to the Map. Does that approach make some sense? Thanks, Matt On Tue, 23 Jun 2015 15:33 Kostiantyn Rybnikov wrote: > Imants, > > You are right. The problem is not in IO here, it's that if you have access > to data-constructor, you can do things like: > > six :: TypeValInt 6 > six = TypeValInt 5 > > Initially, I was making an assumption that you won't be using a > data-constructor. After thinking about it a bit, I should note that my code > isn't much different from just using a "smart constructor" approach, e.g. > hiding a real MyP constructor, and instead providing a function: > > mkMyP (a, b) = MyP (a, b) (b, a) > > and exporting only this function. This would make sure all your users only > create a valid set of data. > > > On Tue, Jun 23, 2015 at 5:05 PM, Imants Cekusins wrote: > >> On 23 June 2015 at 14:54, Kostiantyn Rybnikov wrote: >> > Hi Matt. I don't know how bad is this, but here's what I came up with. >> ... >> >> this modified for IO version accepts any input, including that which >> should have caused error: >> >> or did I do something wrong? >> >> >> {-# LANGUAGE DataKinds #-} >> {-# LANGUAGE KindSignatures #-} >> {-# LANGUAGE ExistentialQuantification #-} >> {-# LANGUAGE PolyKinds #-} >> {-# LANGUAGE StandaloneDeriving #-} >> >> module PairsMatchedKR where >> >> import GHC.TypeLits >> >> data TypeValInt (n::Nat) = TypeValInt Int >> deriving (Show) >> >> one :: TypeValInt 1 >> one = TypeValInt 1 >> >> two :: TypeValInt 2 >> two = TypeValInt 2 >> >> data MyP a b = MyP (TypeValInt a, TypeValInt b) (TypeValInt b, TypeValInt >> a) >> deriving (Show) >> >> main :: IO () >> main = do >> putStrLn "Hello!" >> x1 <- getLine >> x2 <- getLine >> x3 <- getLine >> x4 <- getLine >> >> print (MyP (tvi x1, tvi x2) (tvi x3, tvi x4)) >> >> class TypeVal (g :: a -> *) >> instance TypeVal TypeValInt >> >> data MyPGen a b = forall g. (TypeVal g, Show (g a), Show (g b)) >> => MyPGen (g a, g b) (g b, g a) >> deriving instance Show (MyPGen a b) >> >> >> tvi:: String -> TypeValInt (n::Nat) >> tvi = TypeValInt . read >> _______________________________________________ >> 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 imantc at gmail.com Tue Jun 23 20:14:52 2015 From: imantc at gmail.com (Imants Cekusins) Date: Tue, 23 Jun 2015 22:14:52 +0200 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: > alter its Eq => definition module MatchTuple (MyP) where data MyP t = MyP(t,t) deriving Show instance Eq t => Eq (MyP t) where (==) = match match::Eq t => MyP t-> MyP t -> Bool match (MyP(x1,x2)) (MyP(x3,x4)) | x1 == x3 && x2 == x4 = True | x1 == x4 && x2 == x3 = True | otherwise = False ? From rein.henrichs at gmail.com Tue Jun 23 20:33:55 2015 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Tue, 23 Jun 2015 20:33:55 +0000 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: FYI, Data.Map uses an Ord instance for keys, not an Eq instance. On Tue, Jun 23, 2015 at 1:15 PM Imants Cekusins wrote: > > alter its Eq => definition > > module MatchTuple (MyP) where > > data MyP t = MyP(t,t) deriving Show > instance Eq t => Eq (MyP t) where > (==) = match > > > match::Eq t => MyP t-> MyP t -> Bool > match (MyP(x1,x2)) (MyP(x3,x4)) > | x1 == x3 && x2 == x4 = True > | x1 == x4 && x2 == x3 = True > | otherwise = False > > > ? > _______________________________________________ > 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 imantc at gmail.com Tue Jun 23 20:41:51 2015 From: imantc at gmail.com (Imants Cekusins) Date: Tue, 23 Jun 2015 22:41:51 +0200 Subject: [Haskell-beginners] Structural restrictions in type constructor In-Reply-To: References: Message-ID: > Data.Map uses an Ord instance for keys, not an Eq instance. Cheers Rein Ord instance needs to implement compare then also http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Ord.html From sevcsik at gmail.com Wed Jun 24 14:53:42 2015 From: sevcsik at gmail.com (=?UTF-8?Q?Sevcsik_Andr=C3=A1s?=) Date: Wed, 24 Jun 2015 14:53:42 +0000 Subject: [Haskell-beginners] http-conduit: Changelogs/notes on API changes Message-ID: Hi, I'm trying to update the couchdb-conduit package to use the latest (stackage) version of it's dependencies. Is there any changelog, release notes, or even a blogpost which summarise how the API was changed between different major versions? And in general, is there a common practice for hackage packages on how are API-breaking changes are communicated? Cheers -- Minden j?t, Sevcsik Andr?s -------------- next part -------------- An HTML attachment was scrubbed... URL: From alanbuxton at gmail.com Wed Jun 24 14:56:23 2015 From: alanbuxton at gmail.com (Alan Buxton) Date: Wed, 24 Jun 2015 15:56:23 +0100 Subject: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" In-Reply-To: <01e201d0addc$9f64d420$de2e7c60$@gmail.com> References: <01c301d0adc3$a59137d0$f0b3a770$@gmail.com> <01e201d0addc$9f64d420$de2e7c60$@gmail.com> Message-ID: <028001d0ae8d$f0b09330$d211b990$@gmail.com> Hi all Thanks for the help you gave me on and off list. I wanted to let you know the solution in the end. The issue rested on the old version of cabal that I had (1.16). I had to install a newer version of cabal, but not 1.22, so using: cabal install cabal-install --constraint "Cabal <1.22" The gotcha here is that I had to then adjust my path so that the local ~/.cabal/bin directory comes first in the $PATH to ensure my local cabal was being used. All the best Alan From: Alan Buxton [mailto:alanbuxton at gmail.com] Sent: 23 June 2015 18:47 To: 'The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell' Subject: RE: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" Thanks for the suggestions: Imants: There is library build-depends: base ==4.6.* (The cabal file was generated by cabal init and so I would hope it's legit :)) I installed Haskell on my Ubuntu just by doing sudo apt-get install haskell-platform. Interestingly, if I do use ghc-mod on a real file with some errors in I get unnecessarily verbose error messages similar to described here: http://mail.haskell.org/pipermail/beginners/2015-February/014573.html I wonder if the issues are related somehow? Norbert: I?m not sure what exactly you are suggesting but if I even take the version constraint out of the cabal file so I have build-depends: base (without any version specified) then I get the same issue. From: Beginners [mailto:beginners-bounces at haskell.org] On Behalf Of Norbert Melzer Sent: 23 June 2015 17:49 To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell Subject: Re: [Haskell-beginners] ghc-mod and cabal "could not find module Prelude" Just add base as dependency in the version constraints matching that base that is delivered with your version of GHC. Alan Buxton > schrieb am Di., 23.06.2015, 16:48: Hi I?ve recently set up a new Haskell working environment on Ubuntu 14.04. I installed the Ubuntu packaged version of Haskell platform. My problem is that I can?t now get ghc-mod check to work if there is a cabal file in the current directory. I am using: * ghc-mod 5.2.1.2 compiled by GHC 7.6.3 * cabal 1.16.0.2 See below an extract of trying to run ghc-mod check in a directory that was empty until I just ran cabal init in it: ~/tmp-ghc-mod$ ls Setup.hs tmp-ghc-mod.cabal ~/tmp-ghc-mod$ ghc-mod check Setup.hs Setup.hs:1:1:Could not find module `Prelude'It is a member of the hidden package `base'.Perhaps you need to add `base' to the build-depends in your .cabal file.It is a member of the hidden package `haskell98-2.0.0.2'.Perhaps you need to add `haskell98' to the build-depends in your .cabal file.It is a member of the hidden package `haskell2010-1.1.1.0'.Perhaps you need to add `haskell2010' to the build-depends in your .cabal file.Use -v to see a list of the files searched for. ~/tmp-ghc-mod$ mv tmp-ghc-mod.cabal tmp-ghc-mod.cabal.NOT ~/tmp-ghc-mod$ ls dist Setup.hs tmp-ghc-mod.cabal.NOT ~/tmp-ghc-mod$ ghc-mod check Setup.hs Setup.hs:2:1:Warning: Top-level binding with no type signature: main :: IO () ~/tmp-ghc-mod$ So? ghc-mod behaves as expected when there is no cabal file, but doesn?t behave as expected if there is a cabal file. My google fu isn?t helping me out on this: the only issues I have seen are to do with a change in format of the cabal file in newer versions of cabal. Any ideas? Thanks Alan _______________________________________________ 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 imantc at gmail.com Wed Jun 24 19:52:37 2015 From: imantc at gmail.com (Imants Cekusins) Date: Wed, 24 Jun 2015 21:52:37 +0200 Subject: [Haskell-beginners] Functor fmap: how to Message-ID: There are a few Functor & fmap tutorials. Here is basic use of fmap. If it leaves you confused, please ignore it. module FunctorFmap where {- why maybe & list? Functor instances exist for Maybe & List http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Functor.html#t:Functor expand "instances" -} -- (a -> b) add3:: Int -> Int add3 = (+ 3) -- maybe runMaybe::IO () runMaybe = do print $ maybeFmap $ Just 1 print $ maybeInfixed $ Just 1 print $ maybeFmap Nothing print $ maybeInfixed Nothing -- maybeFmap & maybeInfixed do the same thing. different syntax maybeFmap::Maybe Int -> Maybe Int maybeFmap = fmap add3 maybeInfixed::Maybe Int -> Maybe Int maybeInfixed mi = add3 <$> mi -- list runList::IO () runList = do print $ listFmap [1,2] print $ listInfixed [1,2] -- listFmap & listInfixed do the same thing. different syntax listFmap::[Int] -> [Int] listFmap = fmap add3 listInfixed::[Int] -> [Int] listInfixed l = add3 <$> l From hjgtuyl at chello.nl Wed Jun 24 20:43:23 2015 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Wed, 24 Jun 2015 22:43:23 +0200 Subject: [Haskell-beginners] http-conduit: Changelogs/notes on API changes In-Reply-To: References: Message-ID: On Wed, 24 Jun 2015 16:53:42 +0200, Sevcsik Andr?s wrote: > Hi, > > I'm trying to update the couchdb-conduit package to use the latest > (stackage) version of it's dependencies. > > Is there any changelog, release notes, or even a blogpost which summarise > how the API was changed between different major versions? You can get all change info from the GitHub network graph; hovering over the dots give short description of the changes, click on the dots shows all details: https://github.com/akaspin/couchdb-conduit/network (it is however not clear to me, which version is stored on Hackage) > And in general, is there a common practice for hackage packages on how > are > API-breaking changes are communicated? The version of the package gives some indication, see the Package Versioning Policy, https://wiki.haskell.org/Package_versioning_policy#Version_numbers 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 imantc at gmail.com Thu Jun 25 10:48:51 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 25 Jun 2015 12:48:51 +0200 Subject: [Haskell-beginners] basic use of Applicative Message-ID: module BasicApplicative where -- 2 arg upd2:: Int -> Int -> Int upd2 x1 x2 = x1 * x2 -- 3 arg upd3:: Int -> Int -> Int -> Int upd3 x1 x2 x3 = x1 * x2 + x3 -- pure pureMaybe::Int -> Maybe Int pureMaybe = pure pureList::Int -> [Int] pureList = pure -- maybe maybe2::Maybe Int -> Maybe Int -> Maybe Int maybe2 mi1 mi2 = upd2 <$> mi1 <*> mi2 -- list list2::[Int] -> [Int] -> [Int] list2 l1 l2 = upd2 <$> l1 <*> l2 -- same result as list2 list2p::[Int] -> [Int] -> [Int] list2p l1 l2 = pure upd2 <*> l1 <*> l2 list3::[Int] -> [Int] -> [Int] -> [Int] list3 l1 l2 l3 = upd3 <$> l1 <*> l2 <*> l3 From kc1956 at gmail.com Thu Jun 25 18:04:18 2015 From: kc1956 at gmail.com (KC) Date: Thu, 25 Jun 2015 11:04:18 -0700 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: References: Message-ID: Words? Sentences? -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey On Jun 25, 2015 3:48 AM, "Imants Cekusins" wrote: > module BasicApplicative where > > > -- 2 arg > upd2:: Int -> Int -> Int > upd2 x1 x2 = x1 * x2 > > -- 3 arg > upd3:: Int -> Int -> Int -> Int > upd3 x1 x2 x3 = x1 * x2 + x3 > > > -- pure > pureMaybe::Int -> Maybe Int > pureMaybe = pure > > pureList::Int -> [Int] > pureList = pure > > > -- maybe > maybe2::Maybe Int -> Maybe Int -> Maybe Int > maybe2 mi1 mi2 = upd2 <$> mi1 <*> mi2 > > > -- list > list2::[Int] -> [Int] -> [Int] > list2 l1 l2 = upd2 <$> l1 <*> l2 > > -- same result as list2 > list2p::[Int] -> [Int] -> [Int] > list2p l1 l2 = pure upd2 <*> l1 <*> l2 > > > list3::[Int] -> [Int] -> [Int] -> [Int] > list3 l1 l2 l3 = upd3 <$> l1 <*> l2 <*> l3 > _______________________________________________ > 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 imantc at gmail.com Thu Jun 25 18:30:54 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 25 Jun 2015 20:30:54 +0200 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: References: Message-ID: > Words? > Sentences? You see, these are only short snippets on purpose. There are many books and tutorials which cover Functors & Applicatives at length. This is my first attempt at Functors & Applicatives. Hopefully it gives an idea re: how these may be used. Hopefully these snippets are valid use examples and do not misguide anyone. I do not yet understand the concepts enough to try to explain them. My explanations would most likely confuse or amuse people depending on their experience. These are but self sufficient modules which compile & work. From kc1956 at gmail.com Thu Jun 25 18:44:13 2015 From: kc1956 at gmail.com (KC) Date: Thu, 25 Jun 2015 11:44:13 -0700 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: References: Message-ID: I'm a part time tutor even though I don't look Elizabethan :D Try explaining them to increase your understanding -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey On Jun 25, 2015 11:31 AM, "Imants Cekusins" wrote: > > Words? > > Sentences? > > You see, these are only short snippets on purpose. There are many > books and tutorials which cover Functors & Applicatives at length. > > This is my first attempt at Functors & Applicatives. Hopefully it > gives an idea re: how these may be used. Hopefully these snippets are > valid use examples and do not misguide anyone. > > I do not yet understand the concepts enough to try to explain them. My > explanations would most likely confuse or amuse people depending on > their experience. > > These are but self sufficient modules which compile & work. > _______________________________________________ > 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 Thu Jun 25 18:41:36 2015 From: fa-ml at ariis.it (Francesco Ariis) Date: Thu, 25 Jun 2015 20:41:36 +0200 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: References: Message-ID: <20150625184136.GA1972@casa.casa> On Thu, Jun 25, 2015 at 08:30:54PM +0200, Imants Cekusins wrote: > > Words? > > Sentences? > > You see, these are only short snippets on purpose. There are many > books and tutorials which cover Functors & Applicatives at length. > > This is my first attempt at Functors & Applicatives. Hopefully it > gives an idea re: how these may be used. Hopefully these snippets are > valid use examples and do not misguide anyone. Breadcrumb tutorials [1] have a similar approach; maybe you could collect yours and list them in a single web page, it would be easier to navigate. [1] https://acm.wustl.edu/functional/hs-breads.php From imantc at gmail.com Thu Jun 25 19:02:03 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 25 Jun 2015 21:02:03 +0200 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: References: Message-ID: > Try explaining them to increase your understanding Functor: take a polymorphic type e.g. Maybe a define a functor instance for it (fmap) now we can write an (a -> a) function and apply it to the polymorphic type Applicative: allows to apply (a -> ... -> a) to the polymorphic type for which Functor & Applicative instance is defined ? From imantc at gmail.com Thu Jun 25 19:05:11 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 25 Jun 2015 21:05:11 +0200 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: <20150625184136.GA1972@casa.casa> References: <20150625184136.GA1972@casa.casa> Message-ID: > Breadcrumb tutorials [1] have a similar approach; maybe you could collect yours and list them in a single web page, it would be easier to navigate. > [1] https://acm.wustl.edu/functional/hs-breads.php Interesting. I did not see it before. Thank you for the link. If anyone wants to use these snippets - modified or not - they are free and welcome to do so. Don't blame me though. From imantc at gmail.com Thu Jun 25 19:44:29 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 25 Jun 2015 21:44:29 +0200 Subject: [Haskell-beginners] Functor fmap: how to In-Reply-To: References: Message-ID: as the author just realized :-P, we can fmap (a -> b), too module FunctorAb where -- (a -> b) overTen:: Int -> Bool overTen x | x > 10 = True | otherwise = False -- maybe maybe1::Maybe Int -> Maybe Bool maybe1 mi = overTen <$> mi -- list list1::[Int] -> [Bool] list1 l = overTen <$> l From imantc at gmail.com Thu Jun 25 19:54:13 2015 From: imantc at gmail.com (Imants Cekusins) Date: Thu, 25 Jun 2015 21:54:13 +0200 Subject: [Haskell-beginners] basic use of Applicative In-Reply-To: References: <20150625184136.GA1972@casa.casa> Message-ID: -- (a::Int -> b::Bool) module ApplicativeAb where -- 2 arg add3:: Int -> Bool -> Int add3 x1 addYes | addYes = x1 + 3 | otherwise = x1 main::IO() main = do print $ maybe2 (Just 3) (Just True) print $ maybe2 (Just 3) (Just False) print $ list2 [3] [True] -- maybe maybe2::Maybe Int -> Maybe Bool -> Maybe Int maybe2 mi mb = add3 <$> mi <*> mb -- list list2::[Int] -> [Bool] -> [Int] list2 i b = add3 <$> i <*> b From imantc at gmail.com Fri Jun 26 11:16:02 2015 From: imantc at gmail.com (Imants Cekusins) Date: Fri, 26 Jun 2015 13:16:02 +0200 Subject: [Haskell-beginners] Functor fmap: how to In-Reply-To: References: Message-ID: a Functor instance is defined for IO, so we can fmap (a -> b) over IO, too. not using IO monad it seems ;) module FunctorIO where {- usage: *FunctorIO> main {type something, } -} process:: String -> String process s = s ++ " .. ok" main::IO String main = func getLine func::IO String -> IO String func ios = process <$> ios From imantc at gmail.com Fri Jun 26 11:21:51 2015 From: imantc at gmail.com (Imants Cekusins) Date: Fri, 26 Jun 2015 13:21:51 +0200 Subject: [Haskell-beginners] Functor fmap: how to In-Reply-To: References: Message-ID: .. and an a -> b version: module FunctorIOab where {- usage: *FunctorIOab> main {type something, } -} processAb:: String -> Int processAb = length main::IO Int main = func getLine func::IO String -> IO Int func ios = processAb <$> ios From matt.williams45.mw at gmail.com Fri Jun 26 13:55:46 2015 From: matt.williams45.mw at gmail.com (Matt Williams) Date: Fri, 26 Jun 2015 14:55:46 +0100 Subject: [Haskell-beginners] Defining an Instance of Ord Message-ID: Dear All, I am trying to produce a Map, where the (tricky) idea is that the key is a pair, (t1, t2), and the key is considered identical under ordering. Thus: (t1, t2) is the same as (t2, t1) but (t1, t3) is not the same as (t1,t2). This LOOKS like a equality definition. However, the Map key typeclass is defined as Ord, which requires me to define compare: instance Ord Edge where (Edge s1 _) `compare` (Edge s2 _) = s1 `compare` s2 I am a bit stuck on how to use compare to define this type of eqlaity - any pointers very gratefully received. BW, Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: From petr.vapenka at gmail.com Fri Jun 26 14:11:50 2015 From: petr.vapenka at gmail.com (=?UTF-8?Q?Petr_V=C3=A1penka?=) Date: Fri, 26 Jun 2015 16:11:50 +0200 Subject: [Haskell-beginners] Defining an Instance of Ord In-Reply-To: References: Message-ID: What about using new type and sort the pair before comparing? Dne 26.6.2015 15:56 "Matt Williams" napsal(a): > Dear All, > > I am trying to produce a Map, where the (tricky) idea is that the key is a > pair, (t1, t2), and the key is considered identical under ordering. Thus: > > (t1, t2) is the same as (t2, t1) but > (t1, t3) is not the same as (t1,t2). > > This LOOKS like a equality definition. However, the Map key typeclass is > defined as Ord, which requires me to define compare: > > instance Ord Edge where > (Edge s1 _) `compare` (Edge s2 _) = s1 `compare` s2 > > I am a bit stuck on how to use compare to define this type of eqlaity - any pointers very gratefully received. > > BW, > > Matt > > > > _______________________________________________ > 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 imantc at gmail.com Fri Jun 26 14:26:11 2015 From: imantc at gmail.com (Imants Cekusins) Date: Fri, 26 Jun 2015 16:26:11 +0200 Subject: [Haskell-beginners] Defining an Instance of Ord In-Reply-To: References: Message-ID: > What about using new type and sort the pair before comparing? Matt needs to define Ord instance for (t1,t2) so he can use (t1,t2) in Map in non-standard way. he is not trying to sort or compare (t1,t2) just for the sake of it. I think.. From allbery.b at gmail.com Fri Jun 26 14:29:34 2015 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 26 Jun 2015 10:29:34 -0400 Subject: [Haskell-beginners] Defining an Instance of Ord In-Reply-To: References: Message-ID: On Fri, Jun 26, 2015 at 9:55 AM, Matt Williams wrote: > I am trying to produce a Map, where the (tricky) idea is that the key is a > pair, (t1, t2), and the key is considered identical under ordering. Thus: > > (t1, t2) is the same as (t2, t1) but > (t1, t3) is not the same as (t1,t2). > > This LOOKS like a equality definition. However, the Map key typeclass is > defined as Ord, which requires me to define compare: > You need more than Eq to get a collection which can be searched efficiently. Map uses Ord; Hashmap (in unordered-containers) uses Hashable, and might be more appropriate for this type. You will still have to deal with the pair, however. Ord (or Hashable) is only used internally for searching, so you can define an instance which does not necessarily do anything semantically meaningful. For example, one way to define a `compare` for this is to sort the values in the pairs and then apply compare between them: -- assumes s, t are themselves known by compiler to be Ord instance Ord Edge where (Edge s1 t1) `compare` (Edge s2 t2) = let arb s t = if s < t then (s,t) else (t,s) in arb s1 t1 `compare` arb s2 t2 A similar trick could be used to get a Hashable instance. This would end up being slow for large maps or many lookups. In that case, you might consider a wrapper which applies the above "arb" operation to the key on insert or lookup (the "normalized" key is stored in the map), rather than having to compute it for every node traversed during lookup. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From imantc at gmail.com Fri Jun 26 15:04:18 2015 From: imantc at gmail.com (Imants Cekusins) Date: Fri, 26 Jun 2015 17:04:18 +0200 Subject: [Haskell-beginners] Defining an Instance of Ord In-Reply-To: References: Message-ID: > What about using new type and sort the pair before comparing? > sort the values in the pairs and then apply compare between them now I see what Petr meant. Thank you