From alexander at chenjia.nl Thu May 7 17:01:43 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Thu, 7 May 2020 19:01:43 +0200 (CEST) Subject: [Haskell-beginners] formatting? Message-ID: <1914130608.288460.1588870903300@ichabod.co-bxl> Hi, tensDigit.hs tensDigit :: Integral a => a ->a tensDigit x = d   where xLast = x `div` 10             d         = xLast `mod` 10 prelude> load tensDigit.hs parse error on input ‘=’ Perhaps you need a 'let' in a 'do' block? e.g. 'let x = 5' instead of 'x = 5' 4 |             d         = xLast `mod` 10   |                       ^ [1 of 1] Compiling Main             ( chapter7_8.hs, interpreted ) Failed, no modules loaded. I suspect this has something to do with the spacing (since this is example code) if so could someone explain to me what the rules on spacing are so I can get past this. I am using a simple text editor so if someone has a recommendation for an IDE that simply takes care of this, much obliged!! best, -------------- next part -------------- An HTML attachment was scrubbed... URL: From magnus at therning.org Thu May 7 17:23:55 2020 From: magnus at therning.org (Magnus Therning) Date: Thu, 07 May 2020 19:23:55 +0200 Subject: [Haskell-beginners] formatting? In-Reply-To: <1914130608.288460.1588870903300@ichabod.co-bxl> References: <1914130608.288460.1588870903300@ichabod.co-bxl> Message-ID: <87368bodzo.fsf@therning.org> Alexander Chen writes: > Hi, > > tensDigit.hs > > tensDigit :: Integral a => a ->a > tensDigit x = d > where xLast = x `div` 10 > d = xLast `mod` 10 > > prelude> load tensDigit.hs > parse error on input ‘=’ > Perhaps you need a 'let' in a 'do' block? > e.g. 'let x = 5' instead of 'x = 5' > 4 | d = xLast `mod` 10 | ^ > [1 of 1] Compiling Main ( chapter7_8.hs, interpreted ) > Failed, no modules loaded. > > I suspect this has something to do with the spacing (since this is > example code) if so could someone explain to me what the rules on > spacing are so I can get past this. I am using a simple text editor so > if someone has a recommendation for an IDE that simply takes care of > this, much obliged!! > Try lining up the definitions in the where-clause. That'll do it. tensDigit :: Integral a => a ->a tensDigit x = d where xLast = x `div` 10 d = xLast `mod` 10 /M -- Magnus Therning OpenPGP: 0x927912051716CE39 email: magnus at therning.org twitter: magthe http://magnus.therning.org/ If you can tell the truth, you don't have to remember anything. — Mark Twain -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From nowsnow at 163.com Fri May 8 22:49:20 2020 From: nowsnow at 163.com (nowsnow) Date: Sat, 9 May 2020 06:49:20 +0800 Subject: [Haskell-beginners] formatting? (Alexander Chen) In-Reply-To: References: Message-ID: <364639839.20200509064920@163.com> > I am using a simple text editor > so if someone has a recommendation for an IDE that simply takes care of this, much obliged!! Geany is a powerful, stable and lightweight programmer's text editor that provides tons of useful features without bogging down your workflow. It runs on Linux, Windows and MacOS is translated into over 40 languages, and has built-in support for more than 50 programming languages. From frankdmartinez at gmail.com Sat May 9 00:09:32 2020 From: frankdmartinez at gmail.com (Frank Martinez) Date: Fri, 8 May 2020 20:09:32 -0400 Subject: [Haskell-beginners] formatting? In-Reply-To: <1914130608.288460.1588870903300@ichabod.co-bxl> References: <1914130608.288460.1588870903300@ichabod.co-bxl> Message-ID: Vim (https://wiki.haskell.org/Vim) It takes a little getting used to but you’ll never go back. You’ll use it for so many thing. If Vim really isn’t to your liking, Emacs might. ( https://wiki.haskell.org/Emacs) It’s more of an operating system cleverly disguised as a text editor. Both of these should be your first choice, in my opinion and experience. On Thu, May 7, 2020 at 13:02 Alexander Chen wrote: > Hi, > > tensDigit.hs > > tensDigit :: Integral a => a ->a > tensDigit x = d > where xLast = x `div` 10 > d = xLast `mod` 10 > > prelude> load tensDigit.hs > parse error on input ‘=’ > Perhaps you need a 'let' in a 'do' block? > e.g. 'let x = 5' instead of 'x = 5' > 4 | d = xLast `mod` 10 | ^ > [1 of 1] Compiling Main ( chapter7_8.hs, interpreted ) > Failed, no modules loaded. > > > I suspect this has something to do with the spacing (since this is example > code) if so could someone explain to me what the rules on spacing are so I > can get past this. I am using a simple text editor so if someone has a > recommendation for an IDE that simply takes care of this, much obliged!! > > best, > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- P.S.: I prefer to be reached on BitMessage at BM-2D8txNiU7b84d2tgqvJQdgBog6A69oDAx6 -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at chenjia.nl Wed May 13 14:01:54 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Wed, 13 May 2020 16:01:54 +0200 (CEST) Subject: [Haskell-beginners] Maybe? Message-ID: <2064015795.90167.1589378514390@ichabod.co-bxl> Hi, safeHead.hs safeHead :: [a] -> Maybe a safeHead []    = Nothing safeHead (x:_) = Just x prelude> safeHead [23,1,4,2,4,2] Just 23 Question: what am i doing wrong? best, Alexander -------------- next part -------------- An HTML attachment was scrubbed... URL: From imantc at gmail.com Wed May 13 14:11:47 2020 From: imantc at gmail.com (Imants Cekusins) Date: Wed, 13 May 2020 17:11:47 +0300 Subject: [Haskell-beginners] Maybe? In-Reply-To: <2064015795.90167.1589378514390@ichabod.co-bxl> References: <2064015795.90167.1589378514390@ichabod.co-bxl> Message-ID: > > prelude> safeHead [23,1,4,2,4,2] > Just 23 Looks good. What did you expect to see? -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at chenjia.nl Wed May 13 14:15:22 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Wed, 13 May 2020 16:15:22 +0200 (CEST) Subject: [Haskell-beginners] Maybe? In-Reply-To: References: <2064015795.90167.1589378514390@ichabod.co-bxl> Message-ID: <2080448094.91279.1589379322104@ichabod.co-bxl> I expected  prelude> safeHead [23,1,4,2,4,2] 23 not Just 23 May 13, 2020 4:11:47 PM CEST Imants Cekusins wrote: prelude> safeHead [23,1,4,2,4,2] Just 23 Looks good. What did you expect to see? _______________________________________________ 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 velichko.lefterov at gmail.com Wed May 13 14:17:38 2020 From: velichko.lefterov at gmail.com (Velichko Lefterov) Date: Wed, 13 May 2020 17:17:38 +0300 Subject: [Haskell-beginners] Maybe? In-Reply-To: <2080448094.91279.1589379322104@ichabod.co-bxl> References: <2064015795.90167.1589378514390@ichabod.co-bxl> <2080448094.91279.1589379322104@ichabod.co-bxl> Message-ID: The function returns Maybe a. On Wed, May 13, 2020 at 5:16 PM Alexander Chen wrote: > I expected > > prelude> safeHead [23,1,4,2,4,2] > 23 > > not > Just 23 > > May 13, 2020 4:11:47 PM CEST Imants Cekusins wrote: > > prelude> safeHead [23,1,4,2,4,2] > Just 23 > > > Looks good. > > What did you expect to see? > > _______________________________________________ > 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 Wed May 13 14:32:08 2020 From: imantc at gmail.com (Imants Cekusins) Date: Wed, 13 May 2020 17:32:08 +0300 Subject: [Haskell-beginners] Maybe? In-Reply-To: References: <2064015795.90167.1589378514390@ichabod.co-bxl> <2080448094.91279.1589379322104@ichabod.co-bxl> Message-ID: Maybe a is a sum type. Show instance for sum types displays the constructor. For example, if we used another sum type: Either Int Int, then Left 23 /= Right 23 So we'd be interested to see the constructor to tell them apart. 23 wouldn't be sufficiently clear. On Wed, May 13, 2020 at 5:18 PM Velichko Lefterov < velichko.lefterov at gmail.com> wrote: > The function returns Maybe a. > > On Wed, May 13, 2020 at 5:16 PM Alexander Chen > wrote: > >> I expected >> >> prelude> safeHead [23,1,4,2,4,2] >> 23 >> >> not >> Just 23 >> >> May 13, 2020 4:11:47 PM CEST Imants Cekusins wrote: >> >> prelude> safeHead [23,1,4,2,4,2] >> Just 23 >> >> >> Looks good. >> >> What did you expect to see? >> >> _______________________________________________ >> 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 imantc at gmail.com Wed May 13 14:34:30 2020 From: imantc at gmail.com (Imants Cekusins) Date: Wed, 13 May 2020 17:34:30 +0300 Subject: [Haskell-beginners] Maybe? In-Reply-To: References: <2064015795.90167.1589378514390@ichabod.co-bxl> <2080448094.91279.1589379322104@ichabod.co-bxl> Message-ID: Actually, derived Show instance for _any_ type displays the constructor. I hope this statement is correct ;) -------------- next part -------------- An HTML attachment was scrubbed... URL: From chrysaetos99 at posteo.de Wed May 20 18:26:37 2020 From: chrysaetos99 at posteo.de (chrysaetos99) Date: Wed, 20 May 2020 20:26:37 +0200 Subject: [Haskell-beginners] Code Review of Caesar-Cipher Message-ID: Background ---------- I am a total beginner in Haskell, so after reading the "Starting out"-chapter of "Learn you a Haskell", I wanted to create my first program that actually does something. I decided to do the famous Caesar-Cipher. Code ---- See attachment. Question(s) ----------- - How can this code be improved in general? - Do I follow the style guide of Haskell (indentation, etc.)? - I have a background in imperative languages. Did I do something that is untypical for functional programming languages? I would appreciate any suggestions. --- Please note: I also asked this question on https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation, but didn't receive an answer that really answered all my questions. Kind regards chrysaetos99 -------------- next part -------------- A non-text attachment was scrubbed... Name: caesar.hs Type: text/x-haskell Size: 1294 bytes Desc: not available URL: From danielvandeghinste at gmail.com Wed May 20 21:37:18 2020 From: danielvandeghinste at gmail.com (Daniel van de Ghinste) Date: Wed, 20 May 2020 23:37:18 +0200 Subject: [Haskell-beginners] Code Review of Caesar-Cipher In-Reply-To: References: Message-ID: I’m no guru, so somebody please feel free to correct my advice here. I’m trying to get a bit more active in reading these mailing lists and giving advice as I believe it’ll help me become better in my own understnading. First thing, well done! It works! Nice job for the beginning of your haskell journey :) Ill be focusing on your first and third question. Your indentations seem fine here so far. There are many different approaches you could take as you learn more, but here are some things I noticed: ******************** 1) isAlphabetic :: Char -> Bool isAlphabetic char = char >= 'A' && char <= ‘Z' I feel this would be more readable as a literal, though you function works. The <= && => feel very much like imperative style to me isAlphabetic :: Char -> Bool isAlphabetic char = elem char ['A'..'Z'] That feel nicer to me. ‘Elem' works like ‘in’ in some other languages and has the type: elem :: (Eq a, Foldable t) => a -> t a -> Bool Lists are a ‘foldable t’ as would be a binary tree (or some other type of tree). Just think of ‘foldable’ as something you can iterate over/through. It as something you can iterate over. The ‘..’ Syntax in the expression [‘A’..’Z’] works on any type which is a member of the ‘Enum’ type class, which is to say it has some type of successor/predecessor order. A comes after b, c comes after b and so on. So typing [‘A’..’Z’] just creates a literal list of the characters from ‘A’ to ‘Z’. Come to think of it, the above would be even nicer if you wrote it in ‘point free style’ (notice the lack of a ‘char’ in my expected isAlphabetic function parameters, despite it being in the type signature) which would require you to ‘flip’ the elem function so the Char becomes the second argument expected rather than the first alphabetLength :: Int alphabetLength = length alphabet alphabet :: [Char] alphabet = ['A'..'Z'] isAlphabetic :: Char -> Bool isAlphabetic = flip elem alphabet ****************************** 2) Try to avoid so much logic in your encrypt and decrypt functions (nested ‘if’ ’then’ ‘else’ makes it harder to follow). Also, I don’t know why you are having your functions here return an Int and letting your ‘encrypt’ and ‘decrypt’ functions do the work of changing them back into a Char. It seems to me if you give a Char to your encryptChar function, you should get back an encrypted Char. Make these functions below finish their work. I assume you were tripping yourself up with what to return if isAlphabetic is false, but just return the char value unchanged. Then the type signature of these 2 functions below could be Char -> Int -> Char instead encryptChar :: Char -> Int -> Int encryptChar char shift = if isAlphabetic char -- Only encrypt A...Z then (if ord char + shift > ord 'Z' -- "Z" with shift 3 becomes "C" and not "]" then ord char + shift - alphabetLength else ord char + shift) else ord char decryptChar :: Char -> Int -> Int decryptChar char shift = if isAlphabetic char then (if ord char - shift < ord 'A' then ord char - shift + alphabetLength else ord char - shift) else ord char Also, notice how similar the 2 functions are. These could be combined. The only difference between them is the ‘+’ and ‘-‘ operations switching. Maybe something like the following shiftChar :: Int -> Char -> Char shiftChar n c | isAlphabetic c = chr ((((ord c + n) - base) `mod` alphabetLength) + base) | otherwise = c where base = 65 This version works for negative or positive values of n. So it can be used to encrypt and decrypt. My brackets are a bit ugly, but I’m getting lazy (it’s late here). The use of `mod` here (the infix version of the modulo operator, % in some other languages like python) means we can accept arbitrarily large values of n to our function, and it just wraps around. We can also accept negative values. The pipe syntax ‘|’ is just a neater way of doing if else statements (see guards for more info) The 65 here is because ‘ord' is defined for all possible Char values. You’re defining your valid range for this cipher to capital alphabetic characters, which starts at 65: *Main> fmap ord ['A'..'Z'] [65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90] — the corresponding number for each capital letter in order. If you haven’t come across fmap yet, it’s the same as map for lists, but you can use it on structures other than lists - see Functors later in your Haskell education :) basically it applies the function to each of the value in the list here ************************************ 3) Lastly, your encrypt and decrypt functions encrypt :: String -> Int -> String encrypt string shift = [chr (encryptChar (toUpper x) shift) | x <- string] -- "Loop" through string to encrypt char by char decrypt :: String -> Int -> String decrypt string shift = [chr (decryptChar (toUpper x) shift) | x <- string] I like your use of list comprehensions here :) though as mentioned before I don’t think you should be using the chr function here, rather your encryptChar and decryptChar functions should be doing that to the values they return. Because I changed other pieces in the code, I’ll show you another way of doing this part now. encrypt' :: Int -> String -> String encrypt' x = fmap (shiftChar x) decrypt' :: Int -> String -> String decrypt' x = encrypt' (negate x) Here I’m using ‘point free’ style again only referencing the first of the two parameters expected by encrypt’. Because we changed our other function in answer ******2 on this mail, encrypt’ and decrypt’ are just the inverse of each other. So decrypt' is defined in terms of encrypt’ but just negates the number passed to encrypt’. As you might expect, negate just makes positive numbers negative, and negative ones positive. In encrypt’ I also use fmap again, because in Haskell a String is just a type alias for a list of Characters ( type String = [Char]), so we are just mapping the function shiftChar, with the number already baked in, to each character in the list of character (string) which will be passed to this function. Please find attached my edits to your source file if you wanna see it in full and play around with it. Best regards, Lord_Luvat P.S. Let me know if I’m a bad teacher, or pitching this response at the wrong level :) I’m trying to learn here too. > On 20 May 2020, at 20:26, chrysaetos99 wrote: > > Background > ---------- > I am a total beginner in Haskell, so after reading the "Starting out"-chapter of "Learn you a Haskell", I wanted to create my first program that actually does something. > > I decided to do the famous Caesar-Cipher. > > > Code > ---- > See attachment. > > > Question(s) > > ----------- > > - How can this code be improved in general? > - Do I follow the style guide of Haskell (indentation, etc.)? > - I have a background in imperative languages. Did I do something that is untypical for functional programming languages? > > I would appreciate any suggestions. > > --- > > Please note: I also asked this question on https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation, but didn't receive an answer that really answered all my questions. > > > Kind regards > > chrysaetos99 > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Ceasar.hs Type: application/octet-stream Size: 650 bytes Desc: not available URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From traqueofziche at gmail.com Thu May 21 00:04:57 2020 From: traqueofziche at gmail.com (=?UTF-8?B?6bKN5Yev5paH?=) Date: Wed, 20 May 2020 17:04:57 -0700 Subject: [Haskell-beginners] Code Review of Caesar-Cipher In-Reply-To: References: Message-ID: Hi, For what it's worth, Daniel's suggestion of: ```haskell isAlphabetic char = elem char ['A'..'Z'] ``` does read nicer but would have to traverse `['A'..'Z']` every time. I think what you have is fine, and although relational and boolean operators are also in imperative languages, they behave as pure functions even in imperative languages if subexpressions don't cause side effects. I don't think it's unidiomatic, and especially in this case, "between A and Z" means the same thing as "is one of the letters A, B, C...Z", so the intent of the function is clear as written. Best of all would probably be using `isAlpha` from `Data.Char` (in `base`). Best, toz On Wed, May 20, 2020 at 2:41 PM wrote: > Send Beginners mailing list submissions to > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > or, via email, send a message with subject or body 'help' to > beginners-request at haskell.org > > You can reach the person managing the list at > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Beginners digest..." > > > Today's Topics: > > 1. Code Review of Caesar-Cipher (chrysaetos99) > 2. Re: Code Review of Caesar-Cipher (Daniel van de Ghinste) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Wed, 20 May 2020 20:26:37 +0200 > From: chrysaetos99 > To: beginners at haskell.org > Subject: [Haskell-beginners] Code Review of Caesar-Cipher > Message-ID: > Content-Type: text/plain; charset="utf-8"; Format="flowed" > > Background > ---------- > I am a total beginner in Haskell, so after reading the "Starting > out"-chapter of "Learn you a Haskell", I wanted to create my first > program that actually does something. > > I decided to do the famous Caesar-Cipher. > > > Code > ---- > See attachment. > > > Question(s) > > ----------- > > - How can this code be improved in general? > - Do I follow the style guide of Haskell (indentation, etc.)? > - I have a background in imperative languages. Did I do something that > is untypical for functional programming languages? > > I would appreciate any suggestions. > > --- > > Please note: I also asked this question on > > https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation, > > but didn't receive an answer that really answered all my questions. > > > Kind regards > > chrysaetos99 > > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: caesar.hs > Type: text/x-haskell > Size: 1294 bytes > Desc: not available > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200520/71a523ea/attachment-0001.hs > > > > ------------------------------ > > Message: 2 > Date: Wed, 20 May 2020 23:37:18 +0200 > From: Daniel van de Ghinste > To: The Haskell-Beginners Mailing List - Discussion of primarily > beginner-level topics related to Haskell > Subject: Re: [Haskell-beginners] Code Review of Caesar-Cipher > Message-ID: > Content-Type: text/plain; charset="utf-8" > > I’m no guru, so somebody please feel free to correct my advice here. I’m > trying to get a bit more active in reading these mailing lists and giving > advice as I believe it’ll help me become better in my own understnading. > > First thing, well done! It works! Nice job for the beginning of your > haskell journey :) Ill be focusing on your first and third question. Your > indentations seem fine here so far. > > There are many different approaches you could take as you learn more, but > here are some things I noticed: > > ******************** 1) > isAlphabetic :: Char -> Bool > isAlphabetic char = char >= 'A' && char <= ‘Z' > > I feel this would be more readable as a literal, though you function > works. The <= && => feel very much like imperative style to me > > isAlphabetic :: Char -> Bool > isAlphabetic char = elem char ['A'..'Z'] > > That feel nicer to me. ‘Elem' works like ‘in’ in some other languages and > has the type: > elem :: (Eq a, Foldable t) => a -> t a -> Bool > > Lists are a ‘foldable t’ as would be a binary tree (or some other type of > tree). Just think of ‘foldable’ as something you can iterate over/through. > It as something you can iterate over. > > The ‘..’ Syntax in the expression [‘A’..’Z’] works on any type which is a > member of the ‘Enum’ type class, which is to say it has some type of > successor/predecessor order. A comes after b, c comes after b and so on. > So typing [‘A’..’Z’] just creates a literal list of the characters from > ‘A’ to ‘Z’. > > Come to think of it, the above would be even nicer if you wrote it in > ‘point free style’ (notice the lack of a ‘char’ in my expected isAlphabetic > function parameters, despite it being in the type signature) which would > require you to ‘flip’ the elem function so the Char becomes the second > argument expected rather than the first > > alphabetLength :: Int > alphabetLength = length alphabet > > alphabet :: [Char] > alphabet = ['A'..'Z'] > > isAlphabetic :: Char -> Bool > isAlphabetic = flip elem alphabet > > ****************************** 2) > Try to avoid so much logic in your encrypt and decrypt functions (nested > ‘if’ ’then’ ‘else’ makes it harder to follow). Also, I don’t know why you > are having your functions here return an Int and letting your ‘encrypt’ and > ‘decrypt’ functions do the work of changing them back into a Char. It seems > to me if you give a Char to your encryptChar function, you should get back > an encrypted Char. Make these functions below finish their work. I assume > you were tripping yourself up with what to return if isAlphabetic is false, > but just return the char value unchanged. Then the type signature of these > 2 functions below could be Char -> Int -> Char instead > > > encryptChar :: Char -> Int -> Int > encryptChar char shift = if isAlphabetic char > -- Only encrypt A...Z > then (if ord char + shift > ord 'Z' > -- "Z" with shift 3 becomes "C" and not "]" > then ord char + shift - alphabetLength > else ord char + shift) > else ord char > > decryptChar :: Char -> Int -> Int > decryptChar char shift = if isAlphabetic char > then (if ord char - shift < ord 'A' > then ord char - shift + alphabetLength > else ord char - shift) > else ord char > > Also, notice how similar the 2 functions are. These could be combined. The > only difference between them is the ‘+’ and ‘-‘ operations switching. Maybe > something like the following > shiftChar :: Int -> Char -> Char > shiftChar n c > | isAlphabetic c = chr ((((ord c + n) - base) `mod` alphabetLength) + > base) > | otherwise = c > where base = 65 > This version works for negative or positive values of n. So it can be used > to encrypt and decrypt. My brackets are a bit ugly, but I’m getting lazy > (it’s late here). > The use of `mod` here (the infix version of the modulo operator, % in some > other languages like python) means we can accept arbitrarily large values > of n to our function, and it just wraps around. > We can also accept negative values. > The pipe syntax ‘|’ is just a neater way of doing if else statements (see > guards for more info) > The 65 here is because ‘ord' is defined for all possible Char values. > You’re defining your valid range for this cipher to capital alphabetic > characters, which starts at 65: > > *Main> fmap ord ['A'..'Z'] > [65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90] > — the corresponding number for each capital letter in order. > > If you haven’t come across fmap yet, it’s the same as map for lists, but > you can use it on structures other than lists - see Functors later in your > Haskell education :) > basically it applies the function to each of the value in the list here > > ************************************ 3) > Lastly, your encrypt and decrypt functions > encrypt :: String -> Int -> String > encrypt string shift = [chr (encryptChar (toUpper x) shift) | x <- > string] -- "Loop" through string to encrypt char by char > > decrypt :: String -> Int -> String > decrypt string shift = [chr (decryptChar (toUpper x) shift) | x <- string] > > I like your use of list comprehensions here :) though as mentioned before > I don’t think you should be using the chr function here, rather your > encryptChar and decryptChar functions should be doing that to the values > they return. > > Because I changed other pieces in the code, I’ll show you another way of > doing this part now. > > encrypt' :: Int -> String -> String > encrypt' x = fmap (shiftChar x) > > decrypt' :: Int -> String -> String > decrypt' x = encrypt' (negate x) > > Here I’m using ‘point free’ style again only referencing the first of the > two parameters expected by encrypt’. Because we changed our other function > in answer ******2 on this mail, encrypt’ and decrypt’ are just the inverse > of each other. So decrypt' is defined in terms of encrypt’ but just negates > the number passed to encrypt’. As you might expect, negate just makes > positive numbers negative, and negative ones positive. > > In encrypt’ I also use fmap again, because in Haskell a String is just a > type alias for a list of Characters ( type String = [Char]), so we are just > mapping the function shiftChar, with the number already baked in, to each > character in the list of character (string) which will be passed to this > function. > > Please find attached my edits to your source file if you wanna see it in > full and play around with it. > > Best regards, > Lord_Luvat > > P.S. Let me know if I’m a bad teacher, or pitching this response at the > wrong level :) I’m trying to learn here too. > > > > > On 20 May 2020, at 20:26, chrysaetos99 wrote: > > > > Background > > ---------- > > I am a total beginner in Haskell, so after reading the "Starting > out"-chapter of "Learn you a Haskell", I wanted to create my first program > that actually does something. > > > > I decided to do the famous Caesar-Cipher. > > > > > > Code > > ---- > > See attachment. > > > > > > Question(s) > > > > ----------- > > > > - How can this code be improved in general? > > - Do I follow the style guide of Haskell (indentation, etc.)? > > - I have a background in imperative languages. Did I do something that > is untypical for functional programming languages? > > > > I would appreciate any suggestions. > > > > --- > > > > Please note: I also asked this question on > https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation, > but didn't receive an answer that really answered all my questions. > > > > > > Kind regards > > > > chrysaetos99 > > > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200520/2bb8f793/attachment.html > > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: Ceasar.hs > Type: application/octet-stream > Size: 650 bytes > Desc: not available > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200520/2bb8f793/attachment.obj > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200520/2bb8f793/attachment-0001.html > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > ------------------------------ > > End of Beginners Digest, Vol 143, Issue 5 > ***************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chrysaetos99 at posteo.de Thu May 21 06:36:44 2020 From: chrysaetos99 at posteo.de (chrysaetos99) Date: Thu, 21 May 2020 08:36:44 +0200 Subject: [Haskell-beginners] Code Review of Caesar-Cipher In-Reply-To: References: Message-ID: Hi, thank you for your feedback Daniel an Toz. I now used (most of) your suggestions to improve the code. You can find the result as an attachment. Can I improve this even further? Also, I have put a question in the code (as a comment). Could anyone answer that one also? I would appreciate any answers, and thanks again for your effort. chrysaetos99 On 21.05.20 02:04, 鲍凯文 wrote: > Hi, > > For what it's worth, Daniel's suggestion of: > > ```haskell > isAlphabetic char = elem char ['A'..'Z'] > ``` > > does read nicer but would have to traverse `['A'..'Z']` every time. I > think what you have is fine, and although relational and boolean > operators are also in imperative languages, they behave as pure > functions even in imperative languages if subexpressions don't cause > side effects. I don't think it's unidiomatic, and especially in this > case, "between A and Z" means the same thing as "is one of the letters > A, B, C...Z", so the intent of the function is clear as written. > > Best of all would probably be using `isAlpha` from `Data.Char` (in > `base`). > > Best, > > toz > > On Wed, May 20, 2020 at 2:41 PM > wrote: > > Send Beginners mailing list submissions to > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > or, via email, send a message with subject or body 'help' to > beginners-request at haskell.org > > You can reach the person managing the list at > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Beginners digest..." > > > Today's Topics: > >    1.  Code Review of Caesar-Cipher (chrysaetos99) >    2. Re:  Code Review of Caesar-Cipher (Daniel van de Ghinste) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Wed, 20 May 2020 20:26:37 +0200 > From: chrysaetos99 > > To: beginners at haskell.org > Subject: [Haskell-beginners] Code Review of Caesar-Cipher > Message-ID: > > Content-Type: text/plain; charset="utf-8"; Format="flowed" > > Background > ---------- > I am a total beginner in Haskell, so after reading the "Starting > out"-chapter of "Learn you a Haskell", I wanted to create my first > program that actually does something. > > I decided to do the famous Caesar-Cipher. > > > Code > ---- > See attachment. > > > Question(s) > > ----------- > > - How can this code be improved in general? > - Do I follow the style guide of Haskell (indentation, etc.)? > - I have a background in imperative languages. Did I do something > that > is untypical for functional programming languages? > > I would appreciate any suggestions. > > --- > > Please note: I also asked this question on > https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation, > > but didn't receive an answer that really answered all my questions. > > > Kind regards > > chrysaetos99 > > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: caesar.hs > Type: text/x-haskell > Size: 1294 bytes > Desc: not available > URL: > > > ------------------------------ > > Message: 2 > Date: Wed, 20 May 2020 23:37:18 +0200 > From: Daniel van de Ghinste > > To: The Haskell-Beginners Mailing List - Discussion of primarily >         beginner-level topics related to Haskell > > > Subject: Re: [Haskell-beginners] Code Review of Caesar-Cipher > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > I’m no guru, so somebody please feel free to correct my advice > here. I’m trying to get a bit more active in reading these mailing > lists and giving advice as I believe it’ll help me become better > in my own understnading. > > First thing, well done! It works! Nice job for the beginning of > your haskell journey :) Ill be focusing on your first and third > question. Your indentations seem fine here so far. > > There are many different approaches you could take as you learn > more, but here are some things I noticed: > > ******************** 1) > isAlphabetic :: Char -> Bool > isAlphabetic char = char >= 'A' && char <= ‘Z' > > I feel this would be more readable as a literal, though you > function works. The <= && => feel very much like imperative style > to me > > isAlphabetic :: Char -> Bool > isAlphabetic char = elem char ['A'..'Z'] > > That feel nicer to me. ‘Elem' works like ‘in’ in some other > languages and has the type: > elem :: (Eq a, Foldable t) => a -> t a -> Bool > > Lists are a ‘foldable t’ as would be a binary tree (or some other > type of tree). Just think of ‘foldable’ as something you can > iterate over/through. It as something you can iterate over. > > The ‘..’ Syntax in the expression [‘A’..’Z’] works on any type > which is a member of the ‘Enum’ type class, which is to say it has > some type of successor/predecessor order. A comes after b, c comes > after b and so on. > So typing [‘A’..’Z’] just creates a literal  list of the > characters from ‘A’ to ‘Z’. > > Come to think of it, the above would be even nicer if you wrote it > in ‘point free style’ (notice the lack of a ‘char’ in my expected > isAlphabetic function parameters, despite it being in the type > signature) which would require you to ‘flip’ the elem function so > the Char becomes the second argument expected rather than the first > > alphabetLength :: Int > alphabetLength = length alphabet > > alphabet :: [Char] > alphabet = ['A'..'Z'] > > isAlphabetic :: Char -> Bool > isAlphabetic = flip elem alphabet > > ****************************** 2) > Try to avoid so much logic in your encrypt  and decrypt functions > (nested ‘if’ ’then’ ‘else’ makes it harder to follow). Also, I > don’t know why you are having your functions here return an Int > and letting your ‘encrypt’ and ‘decrypt’ functions do the work of > changing them back into a Char. It seems to me if you give a Char > to your encryptChar function, you should get back an encrypted > Char. Make these functions below finish their work. I assume you > were tripping yourself up with what to return if isAlphabetic is > false, but just return the char value unchanged. Then the type > signature of these 2 functions below could be Char -> Int -> Char > instead > > > encryptChar :: Char -> Int -> Int > encryptChar char shift = if isAlphabetic char                -- > Only encrypt A...Z >                             then (if ord char + shift > ord 'Z'    >          -- "Z" with shift 3 becomes "C" and not "]" >                                     then ord char + shift - > alphabetLength >                                   else ord char + shift) >                          else ord char > > decryptChar :: Char -> Int -> Int > decryptChar char shift = if isAlphabetic char >                             then (if ord char - shift < ord 'A' >                                     then ord char - shift + > alphabetLength >                                   else ord char - shift) >                          else ord char > > Also, notice how similar the 2 functions are. These could be > combined. The only difference between them is the ‘+’ and ‘-‘ > operations switching. Maybe something like the following > shiftChar :: Int -> Char -> Char > shiftChar n c >     | isAlphabetic c = chr ((((ord c + n) - base) `mod` > alphabetLength) + base) >     | otherwise      = c >        where base = 65 > This version works for negative or positive values of n. So it can > be used to encrypt and decrypt. My brackets are a bit ugly, but > I’m getting lazy (it’s late here). > The use of `mod` here (the infix version of the modulo operator, % > in some other languages like python) means we can accept > arbitrarily large values of n to our function, and it just wraps > around. > We can also accept negative values. > The pipe syntax ‘|’ is just a neater way of doing if else > statements (see guards for more info) > The 65 here is because ‘ord' is defined for all possible Char > values. You’re defining your valid range for this cipher to > capital alphabetic characters, which starts at 65: > > *Main> fmap ord ['A'..'Z'] > [65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90] > — the corresponding number for each capital letter in order. > > If you haven’t come across fmap yet, it’s the same as map for > lists, but you can use it on structures other than lists - see > Functors later in your Haskell education :) > basically it applies the function to each of the value in the list > here > > ************************************ 3) > Lastly, your encrypt and decrypt functions > encrypt :: String -> Int -> String > encrypt string shift = [chr (encryptChar (toUpper x) shift) | x <- > string]  -- "Loop" through string to encrypt char by char > > decrypt :: String -> Int -> String > decrypt string shift = [chr (decryptChar (toUpper x) shift) | x <- > string] > > I like your use of list comprehensions here :) though as mentioned > before I don’t think you should be using the chr function here, > rather your encryptChar and decryptChar functions should be doing > that to the values they return. > > Because I changed other pieces in the code, I’ll show you another > way of doing this part now. > > encrypt' :: Int -> String -> String > encrypt' x = fmap (shiftChar x) > > decrypt' :: Int -> String -> String > decrypt' x = encrypt' (negate x) > > Here I’m using ‘point free’ style again only referencing the first > of the two parameters expected by encrypt’. Because we changed our > other function in answer ******2 on this mail, encrypt’ and > decrypt’ are just the inverse of each other. So decrypt' is > defined in terms of encrypt’ but just negates the number passed to > encrypt’. As you might expect, negate just makes positive numbers > negative, and negative ones positive. > > In encrypt’ I also use fmap again, because in Haskell a String is > just a type alias for a list of Characters ( type String = > [Char]), so we are just mapping the function shiftChar, with the > number already baked in,  to each character in the list of > character (string) which will be passed to this function. > > Please find attached my edits to your source file if you wanna see > it in full and play around with it. > > Best regards, > Lord_Luvat > > P.S. Let me know if I’m a bad teacher, or pitching this response > at the wrong level :) I’m trying to learn here too. > > > > > On 20 May 2020, at 20:26, chrysaetos99 > wrote: > > > > Background > > ---------- > > I am a total beginner in Haskell, so after reading the "Starting > out"-chapter of "Learn you a Haskell", I wanted to create my first > program that actually does something. > > > > I decided to do the famous Caesar-Cipher. > > > > > > Code > > ---- > > See attachment. > > > > > > Question(s) > > > > ----------- > > > > - How can this code be improved in general? > > - Do I follow the style guide of Haskell (indentation, etc.)? > > - I have a background in imperative languages. Did I do > something that is untypical for functional programming languages? > > > > I would appreciate any suggestions. > > > > --- > > > > Please note: I also asked this question on > https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation, > but didn't receive an answer that really answered all my questions. > > > > > > Kind regards > > > > chrysaetos99 > > > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: Ceasar.hs > Type: application/octet-stream > Size: 650 bytes > Desc: not available > URL: > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > ------------------------------ > > End of Beginners Digest, Vol 143, Issue 5 > ***************************************** > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: caesar.hs Type: text/x-haskell Size: 811 bytes Desc: not available URL: From danielvandeghinste at gmail.com Thu May 21 07:23:34 2020 From: danielvandeghinste at gmail.com (Daniel van de Ghinste) Date: Thu, 21 May 2020 09:23:34 +0200 Subject: [Haskell-beginners] Code Review of Caesar-Cipher In-Reply-To: References: Message-ID: <34CB55BE-74C9-4696-BC6D-FB3A50C8CDD6@gmail.com> Hi, Happy to help so far. I see your question in the comments of the code, asking why ‘flip' is needed. isAlphabetic :: Char -> Bool isAlphabetic = flip elem alphabet Basically, it’s needed by elem here. Let’s look at the signature of elem Prelude> :t elem elem :: (Eq a, Foldable t) => a -> t a -> Bool Lists [ ] qualify as a Foldable t, so in the type signature let’s replace the ’t a’ with ‘[a]’ for clarity for you. elem :: Eq a => a -> [a] -> Bool So, elem takes an ‘a’ as the first parameter and a 'list of a’ as the second parameter and returns a boolean. But we already have our list, and we won’t have the character we want to check until later! So, flip let’s switch that around! That way we can give elem the second parameter first, so it becomes: Prelude> :t (flip elem) (flip elem) :: (Eq a, Foldable t) => t a -> a -> Bool Or to rewrite it like we did above so it’s easier to read. (flip elem) :: Eq a => [a] -> a -> Bool If you look at the function ‘flip’ you’ll see this. Prelude> :t flip flip :: (a -> b -> c) -> b -> a -> c As a beginner it might be easier for you to read if I make this small change. flip :: (a -> b -> c) -> b -> (a -> c) So flip takes a function which takes an ‘a’ and takes a ‘b’ and returns a ‘c’, it takes a ‘b’, puts that ‘b’ into the function you supplied, and then returns to you a function which takes an ‘a’ and returns a ‘c’. So, if you don’t have flip in there elem alphabet Then you are trying to give a list to elem in the position of it’s first parameter. Does that help? Best regards, Daniel van de Ghinste > On 21 May 2020, at 08:36, chrysaetos99 wrote: > > Hi, > > thank you for your feedback Daniel an Toz. I now used (most of) your suggestions to improve the code. > > You can find the result as an attachment. > > Can I improve this even further? Also, I have put a question in the code (as a comment). Could anyone answer > > that one also? > > I would appreciate any answers, and thanks again for your effort. > > chrysaetos99 > > > > On 21.05.20 02:04, 鲍凯文 wrote: >> Hi, >> >> For what it's worth, Daniel's suggestion of: >> >> ```haskell >> isAlphabetic char = elem char ['A'..'Z'] >> ``` >> >> does read nicer but would have to traverse `['A'..'Z']` every time. I think what you have is fine, and although relational and boolean operators are also in imperative languages, they behave as pure functions even in imperative languages if subexpressions don't cause side effects. I don't think it's unidiomatic, and especially in this case, "between A and Z" means the same thing as "is one of the letters A, B, C...Z", so the intent of the function is clear as written. >> >> Best of all would probably be using `isAlpha` from `Data.Char` (in `base`). >> >> Best, >> >> toz >> >> On Wed, May 20, 2020 at 2:41 PM > wrote: >> Send Beginners mailing list submissions to >> beginners at haskell.org >> >> To subscribe or unsubscribe via the World Wide Web, visit >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> or, via email, send a message with subject or body 'help' to >> beginners-request at haskell.org >> >> You can reach the person managing the list at >> beginners-owner at haskell.org >> >> When replying, please edit your Subject line so it is more specific >> than "Re: Contents of Beginners digest..." >> >> >> Today's Topics: >> >> 1. Code Review of Caesar-Cipher (chrysaetos99) >> 2. Re: Code Review of Caesar-Cipher (Daniel van de Ghinste) >> >> >> ---------------------------------------------------------------------- >> >> Message: 1 >> Date: Wed, 20 May 2020 20:26:37 +0200 >> From: chrysaetos99 > >> To: beginners at haskell.org >> Subject: [Haskell-beginners] Code Review of Caesar-Cipher >> Message-ID: > >> Content-Type: text/plain; charset="utf-8"; Format="flowed" >> >> Background >> ---------- >> I am a total beginner in Haskell, so after reading the "Starting >> out"-chapter of "Learn you a Haskell", I wanted to create my first >> program that actually does something. >> >> I decided to do the famous Caesar-Cipher. >> >> >> Code >> ---- >> See attachment. >> >> >> Question(s) >> >> ----------- >> >> - How can this code be improved in general? >> - Do I follow the style guide of Haskell (indentation, etc.)? >> - I have a background in imperative languages. Did I do something that >> is untypical for functional programming languages? >> >> I would appreciate any suggestions. >> >> --- >> >> Please note: I also asked this question on >> https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation , >> but didn't receive an answer that really answered all my questions. >> >> >> Kind regards >> >> chrysaetos99 >> >> >> -------------- next part -------------- >> A non-text attachment was scrubbed... >> Name: caesar.hs >> Type: text/x-haskell >> Size: 1294 bytes >> Desc: not available >> URL: > >> >> ------------------------------ >> >> Message: 2 >> Date: Wed, 20 May 2020 23:37:18 +0200 >> From: Daniel van de Ghinste > >> To: The Haskell-Beginners Mailing List - Discussion of primarily >> beginner-level topics related to Haskell > >> Subject: Re: [Haskell-beginners] Code Review of Caesar-Cipher >> Message-ID: > >> Content-Type: text/plain; charset="utf-8" >> >> I’m no guru, so somebody please feel free to correct my advice here. I’m trying to get a bit more active in reading these mailing lists and giving advice as I believe it’ll help me become better in my own understnading. >> >> First thing, well done! It works! Nice job for the beginning of your haskell journey :) Ill be focusing on your first and third question. Your indentations seem fine here so far. >> >> There are many different approaches you could take as you learn more, but here are some things I noticed: >> >> ******************** 1) >> isAlphabetic :: Char -> Bool >> isAlphabetic char = char >= 'A' && char <= ‘Z' >> >> I feel this would be more readable as a literal, though you function works. The <= && => feel very much like imperative style to me >> >> isAlphabetic :: Char -> Bool >> isAlphabetic char = elem char ['A'..'Z'] >> >> That feel nicer to me. ‘Elem' works like ‘in’ in some other languages and has the type: >> elem :: (Eq a, Foldable t) => a -> t a -> Bool >> >> Lists are a ‘foldable t’ as would be a binary tree (or some other type of tree). Just think of ‘foldable’ as something you can iterate over/through. It as something you can iterate over. >> >> The ‘..’ Syntax in the expression [‘A’..’Z’] works on any type which is a member of the ‘Enum’ type class, which is to say it has some type of successor/predecessor order. A comes after b, c comes after b and so on. >> So typing [‘A’..’Z’] just creates a literal list of the characters from ‘A’ to ‘Z’. >> >> Come to think of it, the above would be even nicer if you wrote it in ‘point free style’ (notice the lack of a ‘char’ in my expected isAlphabetic function parameters, despite it being in the type signature) which would require you to ‘flip’ the elem function so the Char becomes the second argument expected rather than the first >> >> alphabetLength :: Int >> alphabetLength = length alphabet >> >> alphabet :: [Char] >> alphabet = ['A'..'Z'] >> >> isAlphabetic :: Char -> Bool >> isAlphabetic = flip elem alphabet >> >> ****************************** 2) >> Try to avoid so much logic in your encrypt and decrypt functions (nested ‘if’ ’then’ ‘else’ makes it harder to follow). Also, I don’t know why you are having your functions here return an Int and letting your ‘encrypt’ and ‘decrypt’ functions do the work of changing them back into a Char. It seems to me if you give a Char to your encryptChar function, you should get back an encrypted Char. Make these functions below finish their work. I assume you were tripping yourself up with what to return if isAlphabetic is false, but just return the char value unchanged. Then the type signature of these 2 functions below could be Char -> Int -> Char instead >> >> >> encryptChar :: Char -> Int -> Int >> encryptChar char shift = if isAlphabetic char -- Only encrypt A...Z >> then (if ord char + shift > ord 'Z' -- "Z" with shift 3 becomes "C" and not "]" >> then ord char + shift - alphabetLength >> else ord char + shift) >> else ord char >> >> decryptChar :: Char -> Int -> Int >> decryptChar char shift = if isAlphabetic char >> then (if ord char - shift < ord 'A' >> then ord char - shift + alphabetLength >> else ord char - shift) >> else ord char >> >> Also, notice how similar the 2 functions are. These could be combined. The only difference between them is the ‘+’ and ‘-‘ operations switching. Maybe something like the following >> shiftChar :: Int -> Char -> Char >> shiftChar n c >> | isAlphabetic c = chr ((((ord c + n) - base) `mod` alphabetLength) + base) >> | otherwise = c >> where base = 65 >> This version works for negative or positive values of n. So it can be used to encrypt and decrypt. My brackets are a bit ugly, but I’m getting lazy (it’s late here). >> The use of `mod` here (the infix version of the modulo operator, % in some other languages like python) means we can accept arbitrarily large values of n to our function, and it just wraps around. >> We can also accept negative values. >> The pipe syntax ‘|’ is just a neater way of doing if else statements (see guards for more info) >> The 65 here is because ‘ord' is defined for all possible Char values. You’re defining your valid range for this cipher to capital alphabetic characters, which starts at 65: >> >> *Main> fmap ord ['A'..'Z'] >> [65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90] — the corresponding number for each capital letter in order. >> >> If you haven’t come across fmap yet, it’s the same as map for lists, but you can use it on structures other than lists - see Functors later in your Haskell education :) >> basically it applies the function to each of the value in the list here >> >> ************************************ 3) >> Lastly, your encrypt and decrypt functions >> encrypt :: String -> Int -> String >> encrypt string shift = [chr (encryptChar (toUpper x) shift) | x <- string] -- "Loop" through string to encrypt char by char >> >> decrypt :: String -> Int -> String >> decrypt string shift = [chr (decryptChar (toUpper x) shift) | x <- string] >> >> I like your use of list comprehensions here :) though as mentioned before I don’t think you should be using the chr function here, rather your encryptChar and decryptChar functions should be doing that to the values they return. >> >> Because I changed other pieces in the code, I’ll show you another way of doing this part now. >> >> encrypt' :: Int -> String -> String >> encrypt' x = fmap (shiftChar x) >> >> decrypt' :: Int -> String -> String >> decrypt' x = encrypt' (negate x) >> >> Here I’m using ‘point free’ style again only referencing the first of the two parameters expected by encrypt’. Because we changed our other function in answer ******2 on this mail, encrypt’ and decrypt’ are just the inverse of each other. So decrypt' is defined in terms of encrypt’ but just negates the number passed to encrypt’. As you might expect, negate just makes positive numbers negative, and negative ones positive. >> >> In encrypt’ I also use fmap again, because in Haskell a String is just a type alias for a list of Characters ( type String = [Char]), so we are just mapping the function shiftChar, with the number already baked in, to each character in the list of character (string) which will be passed to this function. >> >> Please find attached my edits to your source file if you wanna see it in full and play around with it. >> >> Best regards, >> Lord_Luvat >> >> P.S. Let me know if I’m a bad teacher, or pitching this response at the wrong level :) I’m trying to learn here too. >> >> >> >> > On 20 May 2020, at 20:26, chrysaetos99 > wrote: >> > >> > Background >> > ---------- >> > I am a total beginner in Haskell, so after reading the "Starting out"-chapter of "Learn you a Haskell", I wanted to create my first program that actually does something. >> > >> > I decided to do the famous Caesar-Cipher. >> > >> > >> > Code >> > ---- >> > See attachment. >> > >> > >> > Question(s) >> > >> > ----------- >> > >> > - How can this code be improved in general? >> > - Do I follow the style guide of Haskell (indentation, etc.)? >> > - I have a background in imperative languages. Did I do something that is untypical for functional programming languages? >> > >> > I would appreciate any suggestions. >> > >> > --- >> > >> > Please note: I also asked this question on https://codereview.stackexchange.com/questions/242529/caesar-cipher-implementation , but didn't receive an answer that really answered all my questions. >> > >> > >> > Kind regards >> > >> > chrysaetos99 >> > >> > >> > _______________________________________________ >> > Beginners mailing list >> > Beginners at haskell.org >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> -------------- next part -------------- >> An HTML attachment was scrubbed... >> URL: > >> -------------- next part -------------- >> A non-text attachment was scrubbed... >> Name: Ceasar.hs >> Type: application/octet-stream >> Size: 650 bytes >> Desc: not available >> URL: > >> -------------- next part -------------- >> An HTML attachment was scrubbed... >> URL: > >> >> ------------------------------ >> >> Subject: Digest Footer >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> >> ------------------------------ >> >> End of Beginners Digest, Vol 143, Issue 5 >> ***************************************** >> >> >> _______________________________________________ >> 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 evildude at live.co.uk Thu May 21 10:45:50 2020 From: evildude at live.co.uk (Josh Diamond) Date: Thu, 21 May 2020 10:45:50 +0000 Subject: [Haskell-beginners] Understanding types and constructors more thoroughly Message-ID: Ok so I have an assessment, first part is: Consider the following declaration for a parameterised type of lists in which Nil represents the empty list, and Cons x xs represent a non-empty list with first element x and remaining list of elements xs: data List a = Nil | Cons a (List a) Am I right in reading it like: Declare a List type which can take any parameter and is constructed by Nil or Cons which itself takes anything and a List of anything? Also it seems strange to define a List without [] or : like in the prelude but I assume it’s just for the purposes of the question. Is the (List a) used just to make the order of evaluation explicit or is it some weird thing with tuples? Ok so the actual question is: Q) Define a recursive function append :: List a -> List a -> List a that appends two lists together to give a single list. So I’d have to do something similar to how append is done in the standard prelude I.e. (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) How do I do pattern matching on a user defined type? I was thinking something like: Nil append List a = List a For the first line but the second line is confusing me. I’ve read some stuff on pattern matching for data constructors but I don’t know how relevant it is here. Maybe something like this would work: Cons a (List a) append List b = a : (List a append List b) But I’m getting ‘Data constructor not in scope’ for everything to do with List...it thinks it’s a data constructor although I’ve defined it as a type above. Any help would be great 😊 Sent from Mail for Windows 10 Sent from Mail for Windows 10 -------------- next part -------------- An HTML attachment was scrubbed... URL: From evildude at live.co.uk Thu May 21 11:09:16 2020 From: evildude at live.co.uk (Josh Diamond) Date: Thu, 21 May 2020 11:09:16 +0000 Subject: [Haskell-beginners] Understanding types and constructors more thoroughly In-Reply-To: References: Message-ID: Actually I worked it out, no need for any help so please ignore Sent from Mail for Windows 10 From: Josh Diamond Sent: 21 May 2020 11:47 To: beginners at haskell.org Subject: [Haskell-beginners] Understanding types and constructors more thoroughly Ok so I have an assessment, first part is: Consider the following declaration for a parameterised type of lists in which Nil represents the empty list, and Cons x xs represent a non-empty list with first element x and remaining list of elements xs: data List a = Nil | Cons a (List a) Am I right in reading it like: Declare a List type which can take any parameter and is constructed by Nil or Cons which itself takes anything and a List of anything? Also it seems strange to define a List without [] or : like in the prelude but I assume it’s just for the purposes of the question. Is the (List a) used just to make the order of evaluation explicit or is it some weird thing with tuples? Ok so the actual question is: Q) Define a recursive function append :: List a -> List a -> List a that appends two lists together to give a single list. So I’d have to do something similar to how append is done in the standard prelude I.e. (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) How do I do pattern matching on a user defined type? I was thinking something like: Nil append List a = List a For the first line but the second line is confusing me. I’ve read some stuff on pattern matching for data constructors but I don’t know how relevant it is here. Maybe something like this would work: Cons a (List a) append List b = a : (List a append List b) But I’m getting ‘Data constructor not in scope’ for everything to do with List...it thinks it’s a data constructor although I’ve defined it as a type above. Any help would be great 😊 Sent from Mail for Windows 10 Sent from Mail for Windows 10 -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at chenjia.nl Fri May 22 18:20:38 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Fri, 22 May 2020 20:20:38 +0200 (CEST) Subject: [Haskell-beginners] MaximumBy Message-ID: <746561064.19225.1590171638348@ichabod.co-bxl> Hi, I want to re-write a function maximumBy (its an assignment). However, I don't get how it works. >maximumBy compare [1,53,9001, 10] 9001 but what does it actually do to get there?  thanks in advance. best, -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielvandeghinste at gmail.com Fri May 22 18:33:33 2020 From: danielvandeghinste at gmail.com (Daniel van de Ghinste (Lord_Luvat)) Date: Fri, 22 May 2020 20:33:33 +0200 Subject: [Haskell-beginners] MaximumBy In-Reply-To: <746561064.19225.1590171638348@ichabod.co-bxl> References: <746561064.19225.1590171638348@ichabod.co-bxl> Message-ID: <95B07D1E-14B7-46C1-9764-15D624F783D7@gmail.com> Hi, Maybe I’m on a different version, but I don’t see a function called maximumBy in my base Prelude. Can you give us a type signature for the function? If you’re not sure how to do that just type: Prelude> :t maximumBy In your ghci interpreter and it should return the type signature of whatever you have after ‘:t ‘ (this works for compound expressions too if you put them in brackets) Perhaps maximumBy is what you’re meant to call your rewrite of the existing function I see called ‘maximum’ (seems to do the same thing). Let me know if thats the case and I can explain how it works. Best regards, Daniel van de Ghinste > On 22 May 2020, at 20:20, Alexander Chen wrote: > > Hi, > > I want to re-write a function maximumBy (its an assignment). > > However, I don't get how it works. > > >maximumBy compare [1,53,9001, 10] > 9001 > > but what does it actually do to get there? > > thanks in advance. > > best, > > > _______________________________________________ > 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 alexander at chenjia.nl Fri May 22 18:52:03 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Fri, 22 May 2020 20:52:03 +0200 (CEST) Subject: [Haskell-beginners] MaximumBy In-Reply-To: <95B07D1E-14B7-46C1-9764-15D624F783D7@gmail.com> References: <746561064.19225.1590171638348@ichabod.co-bxl> <95B07D1E-14B7-46C1-9764-15D624F783D7@gmail.com> Message-ID: <1715418034.21133.1590173523046@ichabod.co-bxl> Hi, maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a its in the Data.List May 22, 2020 8:33:33 PM CEST "Daniel van de Ghinste (Lord_Luvat)" wrote:Hi, Maybe I’m on a different version, but I don’t see a function called maximumBy in my base Prelude. Can you give us a type signature for the function? If you’re not sure how to do that just type: Prelude> :t maximumBy In your ghci interpreter and it should return the type signature of whatever you have after ‘:t ‘ (this works for compound expressions too if you put them in brackets) Perhaps maximumBy is what you’re meant to call your rewrite of the existing function I see called ‘maximum’ (seems to do the same thing). Let me know if thats the case and I can explain how it works. Best regards, Daniel van de Ghinste On 22 May 2020, at 20:20, Alexander Chen wrote: Hi, I want to re-write a function maximumBy (its an assignment). However, I don't get how it works. >maximumBy compare [1,53,9001, 10] 9001 but what does it actually do to get there?  thanks in advance. best, _______________________________________________ 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 magnus at therning.org Fri May 22 19:02:09 2020 From: magnus at therning.org (Magnus Therning) Date: Fri, 22 May 2020 21:02:09 +0200 Subject: [Haskell-beginners] Understanding types and constructors more thoroughly In-Reply-To: References: Message-ID: <87h7w74wum.fsf@therning.org> Josh Diamond writes: > Actually I worked it out, no need for any help so please ignore Please consider writing how you solved it. Sometimes when searching the internet I come upon questions that the questioner then solve on her/his own, but _I_ don't get to see the solution. It robs me of an answer to my question, and the questioner is robbed of feedback and further insights. /M -- Magnus Therning OpenPGP: 0x927912051716CE39 email: magnus at therning.org twitter: magthe http://magnus.therning.org/ You can't depend on your judgement when your imagination is out of focus. — Mark Twain -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From fa-ml at ariis.it Fri May 22 19:10:43 2020 From: fa-ml at ariis.it (Francesco Ariis) Date: Fri, 22 May 2020 21:10:43 +0200 Subject: [Haskell-beginners] MaximumBy In-Reply-To: <746561064.19225.1590171638348@ichabod.co-bxl> References: <746561064.19225.1590171638348@ichabod.co-bxl> Message-ID: <20200522191043.GA14834@extensa> Hello Alexander, Il 22 maggio 2020 alle 20:20 Alexander Chen ha scritto: > Hi, > > I want to re-write a function maximumBy (its an assignment). > > However, I don't get how it works. > > >maximumBy compare [1,53,9001, 10] > 9001 > > but what does it actually do to get there?  Do you know how to use foldr and friends? From utprimum at gmail.com Fri May 22 19:13:49 2020 From: utprimum at gmail.com (Ut Primum) Date: Fri, 22 May 2020 21:13:49 +0200 Subject: [Haskell-beginners] MaximumBy In-Reply-To: <1715418034.21133.1590173523046@ichabod.co-bxl> References: <746561064.19225.1590171638348@ichabod.co-bxl> <95B07D1E-14B7-46C1-9764-15D624F783D7@gmail.com> <1715418034.21133.1590173523046@ichabod.co-bxl> Message-ID: Hi, if it is ok for you to work only with lists (not generic foldables), you could write it this way: maximumBy cmp [x] = x maximumBy cmp (x:y:xs) = if (cmp x y)==GT then maximumBy cmp (x:xs) else maximumBy cmp (y:xs) the signature is maximumBy :: (a -> a -> Ordering) -> [a] -> a Ut Mail priva di virus. www.avg.com <#m_-9203042563784922724_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> Il giorno ven 22 mag 2020 alle ore 20:53 Alexander Chen < alexander at chenjia.nl> ha scritto: > Hi, > > maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a > > its in the Data.List > > May 22, 2020 8:33:33 PM CEST "Daniel van de Ghinste (Lord_Luvat)" < > danielvandeghinste at gmail.com> wrote: > > Hi, > > Maybe I’m on a different version, but I don’t see a function called > maximumBy in my base Prelude. Can you give us a type signature for the > function? If you’re not sure how to do that just type: > Prelude> :t maximumBy > In your ghci interpreter and it should return the type signature of > whatever you have after ‘:t ‘ (this works for compound expressions too if > you put them in brackets) > > Perhaps maximumBy is what you’re meant to call your rewrite of the > existing function I see called ‘maximum’ (seems to do the same thing). Let > me know if thats the case and I can explain how it works. > > > Best regards, > Daniel van de Ghinste > > On 22 May 2020, at 20:20, Alexander Chen wrote: > > Hi, > > I want to re-write a function maximumBy (its an assignment). > > However, I don't get how it works. > > >maximumBy compare [1,53,9001, 10] > 9001 > > but what does it actually do to get there? > > thanks in advance. > > best, > > > _______________________________________________ > 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 > Mail priva di virus. www.avg.com <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielvandeghinste at gmail.com Fri May 22 19:28:05 2020 From: danielvandeghinste at gmail.com (Daniel van de Ghinste (Lord_Luvat)) Date: Fri, 22 May 2020 21:28:05 +0200 Subject: [Haskell-beginners] MaximumBy In-Reply-To: <1715418034.21133.1590173523046@ichabod.co-bxl> References: <746561064.19225.1590171638348@ichabod.co-bxl> <95B07D1E-14B7-46C1-9764-15D624F783D7@gmail.com> <1715418034.21133.1590173523046@ichabod.co-bxl> Message-ID: <7FEE92D8-7E5C-4BA7-9D41-F0930C7959FA@gmail.com> Gotcha. So, maximumBy takes a function as it’s first argument, and a foldable as it’s second argument. If you’re not sure what a foldable is yet, just know it’s something you can fold over, or iterate over, or loop through (whichever phrasing you feel most comfortable with based on languages you’ve previously used). There’s more to it, but you’ll get into that later. Examples of something foldable would be lists or trees. If you look at the type signature of the function you are passing to maximumBy as it’s first argument (‘compare’), you’ll see the class constraint of Ord for whichever data type ‘a’ you pass to the first and second arguments of the ’compare’ function. Prelude Data.List> :t compare compare :: Ord a => a -> a -> Ordering Any data type which is an instance of the Ord type class implements the following functions, including ‘compare’. Prelude Data.List> :i Ord class Eq a => Ord a where compare :: a -> a -> Ordering (<) :: a -> a -> Bool (<=) :: a -> a -> Bool (>) :: a -> a -> Bool (>=) :: a -> a -> Bool max :: a -> a -> a min :: a -> a -> a … more info elided So, the types Int or Float, for example, both have instances of the Ord type class. This means you can take 2 Ints and pass them to compare and you’ll get back an Ordering (Ordering is its own data type). Prelude Data.List> compare 1 2 LT Prelude Data.List> compare 2 2 EQ Prelude Data.List> compare 3 2 GT Prelude Data.List> :i Ordering data Ordering = LT | EQ | GT -- Defined in ‘GHC.Types’ LT stands for Less Than, EQ for Equal, and GT for Greater Than. So, maximumBy takes a foldable (let’s say a list, for example) and uses the compare function on 2 instances of the data type held in the list at a time. Each time the result of a comparison is GT, it takes the value that produced that GT result and keeps comparing that value to the others in the list until it finds another value which produces GT or it reaches the end of the list. It then gives you back the ‘greatest’ value it found after ‘folding’ over the list. Exactly how this comparison is done in any more detail relies on you understanding folding and foldables. I hope this helped and didn’t just make it worse by being too verbose. Lemme know if you’ve got it now, or if the actual details of how folding is carried out is what’s tripping you up. Best regards, Daniel van de Ghinste > On 22 May 2020, at 20:52, Alexander Chen wrote: > > Hi, > > maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a > > its in the Data.List > > May 22, 2020 8:33:33 PM CEST "Daniel van de Ghinste (Lord_Luvat)" wrote: >> >> Hi, >> >> Maybe I’m on a different version, but I don’t see a function called maximumBy in my base Prelude. Can you give us a type signature for the function? If you’re not sure how to do that just type: >> Prelude> :t maximumBy >> In your ghci interpreter and it should return the type signature of whatever you have after ‘:t ‘ (this works for compound expressions too if you put them in brackets) >> >> Perhaps maximumBy is what you’re meant to call your rewrite of the existing function I see called ‘maximum’ (seems to do the same thing). Let me know if thats the case and I can explain how it works. >> >> >> Best regards, >> Daniel van de Ghinste >> >>> On 22 May 2020, at 20:20, Alexander Chen > wrote: >>> >>> Hi, >>> >>> I want to re-write a function maximumBy (its an assignment). >>> >>> However, I don't get how it works. >>> >>> >maximumBy compare [1,53,9001, 10] >>> 9001 >>> >>> but what does it actually do to get there? >>> >>> thanks in advance. >>> >>> best, >>> >>> >>> _______________________________________________ >>> 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 nowsnow at 163.com Sat May 23 00:02:10 2020 From: nowsnow at 163.com (nowsnow) Date: Sat, 23 May 2020 08:02:10 +0800 Subject: [Haskell-beginners] MaximumBy (Alexander Chen) In-Reply-To: References: Message-ID: <423640237.20200523080210@163.com> maxinumBy::(Foldable t, Ord a) => t a -> a maxinumBy = foldr1 max > Hi, > I want to re-write a function maximumBy (its an assignment). > However, I don't get how it works. >>maximumBy compare [1,53,9001, 10] > 9001 > but what does it actually do to get there?  > thanks in advance. > best, > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > From Leonhard.Applis at protonmail.com Sun May 24 16:30:22 2020 From: Leonhard.Applis at protonmail.com (Leonhard Applis) Date: Sun, 24 May 2020 16:30:22 +0000 Subject: [Haskell-beginners] Linking C++ in Cabal Message-ID: <51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@protonmail.com> Hello, I want to use a foreign C++ Function in a Haskell Library, and the Library in a Haskell Program. The C++ function is separate in a file and I have a header file.  I made a minimal reproducing repository. The closes I have found is this repository which wraps the c++ in c and makes a full library, needing a makefile etc. So while I think I'd get it working like that, it looks to be quite a lot to do for my simple task. the repository structure looks as follows: Projekt - cpp-src - some.cpp - some.h - lib-src - CPPLib.hs - program-src - program.hs - project.cabal And my (currently failing) project.cabal the following: cabal-version: 3.0 name: cpp_lib [...] library exposed-modules: CPPLib other-extensions: ForeignFunctionInterface build-depends: base hs-source-dirs: lib-src default-language: Haskell2010 include-dirs: ./cpp-src cxx-sources: ./cpp-src/some.cpp install-includes: ./cpp-src/some.h executable CPPApp main-is: program.hs default-language: Haskell2010 build-depends: HaskellForeignCPP, base hs-source-dirs: program-src The some.cpp is trivial for this case lets assume its a function multiply :: Int -> Int -> Int, and both .cpp and .h are well-formed and don't have further dependencies. The library compiles fine, but when building the executable it fails telling me collect2: error: ld returned 1 exit status `gcc' failed in phase `Linker'. (Exit code: 1) Can someone help me out? I find very little documentation on this topic. I know there is Inline-CPP which would help as well, but I just very much like the idea of having a nice separate file and interface for modularity. best Leonhard -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 477 bytes Desc: OpenPGP digital signature URL: From Leonhard.Applis at protonmail.com Mon May 25 13:00:03 2020 From: Leonhard.Applis at protonmail.com (Leonhard Applis) Date: Mon, 25 May 2020 13:00:03 +0000 Subject: [Haskell-beginners] Linking C++ in Cabal - repository Link Message-ID: Ups, in my mailing list the links have disappeared. Just in case: The minimal reproducing repository: https://github.com/Twonki/HaskellForeingCPPMinimal The repository from Aditya Siram with C and makefile: https://github.com/deech/CPlusPlusBindings best Leonhard ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Monday, May 25, 2020 2:00 PM, wrote: > Send Beginners mailing list submissions to > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > or, via email, send a message with subject or body 'help' to > beginners-request at haskell.org > > You can reach the person managing the list at > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Beginners digest..." > > Today's Topics: > > 1. Linking C++ in Cabal (Leonhard Applis) > > > Message: 1 > Date: Sun, 24 May 2020 16:30:22 +0000 > From: Leonhard Applis Leonhard.Applis at protonmail.com > To: "beginners at haskell.org" beginners at haskell.org > Subject: [Haskell-beginners] Linking C++ in Cabal > Message-ID: > 51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@protonmail.com > > Content-Type: text/plain; charset="utf-8" > > Hello, > > I want to use a foreign C++ Function in a Haskell Library, and the Library in a Haskell Program. > The C++ function is separate in a file and I have a header file.  > I made a minimal reproducing repository. > > The closes I have found is this repository which wraps the c++ in c and makes a full library, needing a makefile etc. > So while I think I'd get it working like that, it looks to be quite a lot to do for my simple task. > > the repository structure looks as follows: > > Projekt > > - cpp-src > - some.cpp > - some.h > - lib-src > - CPPLib.hs > - program-src > - program.hs > - project.cabal > > And my (currently failing) project.cabal the following: > > cabal-version: 3.0 > name: cpp_lib > [...] > library > exposed-modules: CPPLib > other-extensions: ForeignFunctionInterface > build-depends: base > hs-source-dirs: lib-src > default-language: Haskell2010 > include-dirs: ./cpp-src > cxx-sources: ./cpp-src/some.cpp > install-includes: ./cpp-src/some.h > > executable CPPApp > main-is: program.hs > default-language: Haskell2010 > build-depends: HaskellForeignCPP, > base > hs-source-dirs: program-src > > The some.cpp is trivial for this case lets assume its a function multiply :: Int -> Int -> Int, and both .cpp and .h are well-formed and don't have further dependencies. > > > The library compiles fine, but when building the executable it fails telling me > > collect2: error: ld returned 1 exit status > `gcc' failed in phase`Linker'. (Exit code: 1) > > Can someone help me out? > I find very little documentation on this topic. > > I know there is Inline-CPP which would help as well, but I just very much like the idea of having a nice separate file and interface for modularity. > > best > Leonhard > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.html > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: signature.asc > Type: application/pgp-signature > Size: 477 bytes > Desc: OpenPGP digital signature > URL: http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.sig > > -- > > Subject: Digest Footer > > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > --------------------------------------------------------------------------------------------------------- > > End of Beginners Digest, Vol 143, Issue 12 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 477 bytes Desc: OpenPGP digital signature URL: From traqueofziche at gmail.com Mon May 25 23:45:09 2020 From: traqueofziche at gmail.com (=?UTF-8?B?6bKN5Yev5paH?=) Date: Mon, 25 May 2020 16:45:09 -0700 Subject: [Haskell-beginners] Linking C++ in Cabal In-Reply-To: References: Message-ID: Hi, Would it be possible to upload your full repo somewhere so people could see everything and possibly reproduce this? Thanks, toz On Mon, May 25, 2020 at 5:03 AM wrote: > Send Beginners mailing list submissions to > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > or, via email, send a message with subject or body 'help' to > beginners-request at haskell.org > > You can reach the person managing the list at > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Beginners digest..." > > > Today's Topics: > > 1. Linking C++ in Cabal (Leonhard Applis) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sun, 24 May 2020 16:30:22 +0000 > From: Leonhard Applis > To: "beginners at haskell.org" > Subject: [Haskell-beginners] Linking C++ in Cabal > Message-ID: > > <51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@ > protonmail.com> > > Content-Type: text/plain; charset="utf-8" > > Hello, > > I want to use a foreign C++ Function in a Haskell Library, and the Library > in a Haskell Program. > The C++ function is separate in a file and I have a header file. > I made a minimal reproducing repository. > > The closes I have found is this repository which wraps the c++ in c and > makes a full library, needing a makefile etc. > So while I think I'd get it working like that, it looks to be quite a lot > to do for my simple task. > > the repository structure looks as follows: > > Projekt > > - cpp-src > > - some.cpp > - some.h > > - lib-src > > - CPPLib.hs > > - program-src > > - program.hs > > - project.cabal > > > > And my (currently failing) project.cabal the following: > > cabal-version: 3.0 > name: cpp_lib > [...] > library > exposed-modules: CPPLib > other-extensions: ForeignFunctionInterface > build-depends: base > hs-source-dirs: lib-src > default-language: Haskell2010 > include-dirs: ./cpp-src > cxx-sources: ./cpp-src/some.cpp > install-includes: ./cpp-src/some.h > > executable CPPApp > main-is: program.hs > default-language: Haskell2010 > build-depends: HaskellForeignCPP, > base > hs-source-dirs: program-src > > The some.cpp is trivial for this case lets assume its a function multiply > :: Int -> Int -> Int, and both .cpp and .h are well-formed and don't have > further dependencies. > > The library compiles fine, but when building the executable it fails > telling me > > collect2: error: ld returned 1 exit status > `gcc' failed in phase `Linker'. (Exit code: 1) > > Can someone help me out? > I find very little documentation on this topic. > > I know there is Inline-CPP which would help as well, but I just very much > like the idea of having a nice separate file and interface for modularity. > > best > Leonhard > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.html > > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: signature.asc > Type: application/pgp-signature > Size: 477 bytes > Desc: OpenPGP digital signature > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.sig > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > ------------------------------ > > End of Beginners Digest, Vol 143, Issue 12 > ****************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From traqueofziche at gmail.com Tue May 26 20:03:13 2020 From: traqueofziche at gmail.com (=?UTF-8?B?6bKN5Yev5paH?=) Date: Tue, 26 May 2020 13:03:13 -0700 Subject: [Haskell-beginners] Linking C++ in Cabal In-Reply-To: References: Message-ID: Hi, So I tried it out, and there're a couple of things: - Declaring a function as `static` will hide it from anything other than the current translation unit, AFAIK, which means that you won't be able to link it to anything else; the symbol won't be visible (you can verify using `objdump`). - For C++ functions, you need to suppress name-mangling since Haskell's FFI doesn't know about that. With your repo as is, the symbol corresponding to the `multiply` function is not...`multiply`: ``` dist-newstyle/build/x86_64-linux/ghc-8.6.5/HaskellForeignCPP-0.0.1/build/cpp-src/some.o: file format elf64-x86-64 SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 some.cpp 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 l d .bss 0000000000000000 .bss 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 g F .text 0000000000000006 _Z8multiplyii ``` so you just need to wrap every exposed function in `extern "C"` blocks, like it's explained here: https://www.geeksforgeeks.org/extern-c-in-c/. With `extern "C"` and removing `static`: ``` dist-newstyle/build/x86_64-linux/ghc-8.6.5/HaskellForeignCPP-0.0.1/build/cpp-src/some.o: file format elf64-x86-64 SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 some.cpp 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 l d .bss 0000000000000000 .bss 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 g F .text 0000000000000006 multiply ``` ...and everything builds fine. Best, toz On Tue, May 26, 2020 at 5:03 AM wrote: > Send Beginners mailing list submissions to > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > or, via email, send a message with subject or body 'help' to > beginners-request at haskell.org > > You can reach the person managing the list at > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Beginners digest..." > > > Today's Topics: > > 1. Re: Linking C++ in Cabal - repository Link (Leonhard Applis) > 2. Re: Linking C++ in Cabal (鲍凯文) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Mon, 25 May 2020 13:00:03 +0000 > From: Leonhard Applis > To: "beginners at haskell.org" > Subject: Re: [Haskell-beginners] Linking C++ in Cabal - repository > Link > Message-ID: > > protonmail.com> > > Content-Type: text/plain; charset="utf-8" > > Ups, in my mailing list the links have disappeared. > Just in case: > > > The minimal reproducing repository: > > https://github.com/Twonki/HaskellForeingCPPMinimal > > The repository from Aditya Siram with C and makefile: > > https://github.com/deech/CPlusPlusBindings > > best > Leonhard > > > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ > On Monday, May 25, 2020 2:00 PM, wrote: > > > Send Beginners mailing list submissions to > > beginners at haskell.org > > > > > To subscribe or unsubscribe via the World Wide Web, visit > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > or, via email, send a message with subject or body 'help' to > > beginners-request at haskell.org > > > > > You can reach the person managing the list at > > beginners-owner at haskell.org > > > > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of Beginners digest..." > > > > > Today's Topics: > > > > > 1. Linking C++ in Cabal (Leonhard Applis) > > > > > > > > Message: 1 > > Date: Sun, 24 May 2020 16:30:22 +0000 > > From: Leonhard Applis Leonhard.Applis at protonmail.com > > To: "beginners at haskell.org" beginners at haskell.org > > Subject: [Haskell-beginners] Linking C++ in Cabal > > Message-ID: > > > 51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@ > protonmail.com > > > > > Content-Type: text/plain; charset="utf-8" > > > > > Hello, > > > > > I want to use a foreign C++ Function in a Haskell Library, and the > Library in a Haskell Program. > > The C++ function is separate in a file and I have a header file. > > I made a minimal reproducing repository. > > > > > The closes I have found is this repository which wraps the c++ in c and > makes a full library, needing a makefile etc. > > So while I think I'd get it working like that, it looks to be quite a > lot to do for my simple task. > > > > > the repository structure looks as follows: > > > > > Projekt > > > > > - cpp-src > > - some.cpp > > - some.h > > - lib-src > > - CPPLib.hs > > - program-src > > - program.hs > > - project.cabal > > > > > And my (currently failing) project.cabal the following: > > > > > cabal-version: 3.0 > > name: cpp_lib > > [...] > > library > > exposed-modules: CPPLib > > other-extensions: ForeignFunctionInterface > > build-depends: base > > hs-source-dirs: lib-src > > default-language: Haskell2010 > > include-dirs: ./cpp-src > > cxx-sources: ./cpp-src/some.cpp > > install-includes: ./cpp-src/some.h > > > > > executable CPPApp > > main-is: program.hs > > default-language: Haskell2010 > > build-depends: HaskellForeignCPP, > > base > > hs-source-dirs: program-src > > > > > The some.cpp is trivial for this case lets assume its a function > multiply :: Int -> Int -> Int, and both .cpp and .h are well-formed and > don't have further dependencies. > > > > > > > > The library compiles fine, but when building the executable it fails > telling me > > > > > collect2: error: ld returned 1 exit status > > `gcc' failed in phase`Linker'. (Exit code: 1) > > > > > Can someone help me out? > > I find very little documentation on this topic. > > > > > I know there is Inline-CPP which would help as well, but I just very > much like the idea of having a nice separate file and interface for > modularity. > > > > > best > > Leonhard > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.html > > -------------- next part -------------- > > A non-text attachment was scrubbed... > > Name: signature.asc > > Type: application/pgp-signature > > Size: 477 bytes > > Desc: OpenPGP digital signature > > URL: > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.sig > > > > > -- > > > > > Subject: Digest Footer > > > > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > > > > > > --------------------------------------------------------------------------------------------------------- > > > > > End of Beginners Digest, Vol 143, Issue 12 > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: signature.asc > Type: application/pgp-signature > Size: 477 bytes > Desc: OpenPGP digital signature > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200525/0e889731/attachment-0001.sig > > > > ------------------------------ > > Message: 2 > Date: Mon, 25 May 2020 16:45:09 -0700 > From: 鲍凯文 > To: beginners at haskell.org > Subject: Re: [Haskell-beginners] Linking C++ in Cabal > Message-ID: > XNqEdg3ox2Q at mail.gmail.com> > Content-Type: text/plain; charset="utf-8" > > Hi, > > Would it be possible to upload your full repo somewhere so people could see > everything and possibly reproduce this? > > Thanks, > > toz > > On Mon, May 25, 2020 at 5:03 AM wrote: > > > Send Beginners mailing list submissions to > > beginners at haskell.org > > > > To subscribe or unsubscribe via the World Wide Web, visit > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > or, via email, send a message with subject or body 'help' to > > beginners-request at haskell.org > > > > You can reach the person managing the list at > > beginners-owner at haskell.org > > > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of Beginners digest..." > > > > > > Today's Topics: > > > > 1. Linking C++ in Cabal (Leonhard Applis) > > > > > > ---------------------------------------------------------------------- > > > > Message: 1 > > Date: Sun, 24 May 2020 16:30:22 +0000 > > From: Leonhard Applis > > To: "beginners at haskell.org" > > Subject: [Haskell-beginners] Linking C++ in Cabal > > Message-ID: > > > > > <51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@ > > protonmail.com> > > > > Content-Type: text/plain; charset="utf-8" > > > > Hello, > > > > I want to use a foreign C++ Function in a Haskell Library, and the > Library > > in a Haskell Program. > > The C++ function is separate in a file and I have a header file. > > I made a minimal reproducing repository. > > > > The closes I have found is this repository which wraps the c++ in c and > > makes a full library, needing a makefile etc. > > So while I think I'd get it working like that, it looks to be quite a lot > > to do for my simple task. > > > > the repository structure looks as follows: > > > > Projekt > > > > - cpp-src > > > > - some.cpp > > - some.h > > > > - lib-src > > > > - CPPLib.hs > > > > - program-src > > > > - program.hs > > > > - project.cabal > > > > > > > > And my (currently failing) project.cabal the following: > > > > cabal-version: 3.0 > > name: cpp_lib > > [...] > > library > > exposed-modules: CPPLib > > other-extensions: ForeignFunctionInterface > > build-depends: base > > hs-source-dirs: lib-src > > default-language: Haskell2010 > > include-dirs: ./cpp-src > > cxx-sources: ./cpp-src/some.cpp > > install-includes: ./cpp-src/some.h > > > > executable CPPApp > > main-is: program.hs > > default-language: Haskell2010 > > build-depends: HaskellForeignCPP, > > base > > hs-source-dirs: program-src > > > > The some.cpp is trivial for this case lets assume its a function multiply > > :: Int -> Int -> Int, and both .cpp and .h are well-formed and don't have > > further dependencies. > > > > The library compiles fine, but when building the executable it fails > > telling me > > > > collect2: error: ld returned 1 exit status > > `gcc' failed in phase `Linker'. (Exit code: 1) > > > > Can someone help me out? > > I find very little documentation on this topic. > > > > I know there is Inline-CPP which would help as well, but I just very much > > like the idea of having a nice separate file and interface for > modularity. > > > > best > > Leonhard > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > > > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.html > > > > > -------------- next part -------------- > > A non-text attachment was scrubbed... > > Name: signature.asc > > Type: application/pgp-signature > > Size: 477 bytes > > Desc: OpenPGP digital signature > > URL: < > > > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.sig > > > > > > > ------------------------------ > > > > Subject: Digest Footer > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > > > ------------------------------ > > > > End of Beginners Digest, Vol 143, Issue 12 > > ****************************************** > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.haskell.org/pipermail/beginners/attachments/20200525/002f0b3f/attachment-0001.html > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > ------------------------------ > > End of Beginners Digest, Vol 143, Issue 13 > ****************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Leonhard.Applis at protonmail.com Wed May 27 06:55:50 2020 From: Leonhard.Applis at protonmail.com (Leonhard Applis) Date: Wed, 27 May 2020 06:55:50 +0000 Subject: [Haskell-beginners] Linking C++ in Cabal Message-ID: Thanks Toz! Works like a charm. Repository is updated for anyone interested. Beginners Mailing list is the best <3 ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Tuesday, May 26, 2020 10:01 PM, wrote: > Send Beginners mailing list submissions to > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > or, via email, send a message with subject or body 'help' to > beginners-request at haskell.org > > You can reach the person managing the list at > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Beginners digest..." > > Today's Topics: > > 1. Re: Linking C++ in Cabal (鲍凯文) > > > Message: 1 > Date: Tue, 26 May 2020 13:03:13 -0700 > From: 鲍凯文 traqueofziche at gmail.com > To: beginners at haskell.org > Subject: Re: [Haskell-beginners] Linking C++ in Cabal > Message-ID: > CAMjcG+FisqcazdRV14Hut7QS1-37tyhXptZG2prNH7-90aswmA at mail.gmail.com > Content-Type: text/plain; charset="utf-8" > > Hi, > > So I tried it out, and there're a couple of things: > > - Declaring a function as `static` will hide it from anything other than > the current translation unit, AFAIK, which means that you won't be able to > link it to anything else; the symbol won't be visible (you can verify using > `objdump`). > > - For C++ functions, you need to suppress name-mangling since Haskell's FFI > doesn't know about that. With your repo as is, the symbol corresponding to > the `multiply` function is not...`multiply`: > > > dist-newstyle/build/x86_64-linux/ghc-8.6.5/HaskellForeignCPP-0.0.1/build/cpp-src/some.o: > file format elf64-x86-64 > > SYMBOL TABLE: > 0000000000000000 l df *ABS* 0000000000000000 some.cpp > 0000000000000000 l d .text 0000000000000000 .text > 0000000000000000 l d .data 0000000000000000 .data > 0000000000000000 l d .bss 0000000000000000 .bss > 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack > 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame > 0000000000000000 l d .comment 0000000000000000 .comment > 0000000000000000 g F .text 0000000000000006 _Z8multiplyii > > > so you just need to wrap every exposed function in `extern "C"` blocks, > like it's explained here: https://www.geeksforgeeks.org/extern-c-in-c/. > > With `extern "C"` and removing `static`: > > dist-newstyle/build/x86_64-linux/ghc-8.6.5/HaskellForeignCPP-0.0.1/build/cpp-src/some.o: > file format elf64-x86-64 > > SYMBOL TABLE: > 0000000000000000 l df *ABS* 0000000000000000 some.cpp > 0000000000000000 l d .text 0000000000000000 .text > 0000000000000000 l d .data 0000000000000000 .data > 0000000000000000 l d .bss 0000000000000000 .bss > 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack > 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame > 0000000000000000 l d .comment 0000000000000000 .comment > 0000000000000000 g F .text 0000000000000006 multiply > > > ...and everything builds fine. > > Best, > > toz > > On Tue, May 26, 2020 at 5:03 AM beginners-request at haskell.org wrote: > > > Send Beginners mailing list submissions to > > beginners at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > or, via email, send a message with subject or body 'help' to > > beginners-request at haskell.org > > You can reach the person managing the list at > > beginners-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of Beginners digest..." > > Today's Topics: > > > > 1. Re: Linking C++ in Cabal - repository Link (Leonhard Applis) > > 2. Re: Linking C++ in Cabal (鲍凯文) > > > > Message: 1 > > Date: Mon, 25 May 2020 13:00:03 +0000 > > From: Leonhard Applis Leonhard.Applis at protonmail.com > > To: "beginners at haskell.org" beginners at haskell.org > > Subject: Re: [Haskell-beginners] Linking C++ in Cabal - repository > > Link > > Message-ID: > > > protonmail.com> > > Content-Type: text/plain; charset="utf-8" > > Ups, in my mailing list the links have disappeared. > > Just in case: > > The minimal reproducing repository: > > https://github.com/Twonki/HaskellForeingCPPMinimal > > The repository from Aditya Siram with C and makefile: > > https://github.com/deech/CPlusPlusBindings > > best > > Leonhard > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ > > On Monday, May 25, 2020 2:00 PM, beginners-request at haskell.org wrote: > > > > > Send Beginners mailing list submissions to > > > beginners at haskell.org > > > > > To subscribe or unsubscribe via the World Wide Web, visit > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > or, via email, send a message with subject or body 'help' to > > > beginners-request at haskell.org > > > > > You can reach the person managing the list at > > > beginners-owner at haskell.org > > > > > When replying, please edit your Subject line so it is more specific > > > than "Re: Contents of Beginners digest..." > > > > > Today's Topics: > > > > > 1. Linking C++ in Cabal (Leonhard Applis) > > > > > > > > > > Message: 1 > > > Date: Sun, 24 May 2020 16:30:22 +0000 > > > From: Leonhard Applis Leonhard.Applis at protonmail.com > > > To: "beginners at haskell.org" beginners at haskell.org > > > Subject: [Haskell-beginners] Linking C++ in Cabal > > > Message-ID: > > > > 51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@ > > protonmail.com > > > > > > > > > > Content-Type: text/plain; charset="utf-8" > > > > > Hello, > > > > > I want to use a foreign C++ Function in a Haskell Library, and the > > > Library in a Haskell Program. > > > The C++ function is separate in a file and I have a header file. > > > I made a minimal reproducing repository. > > > > > The closes I have found is this repository which wraps the c++ in c and > > > makes a full library, needing a makefile etc. > > > So while I think I'd get it working like that, it looks to be quite a > > > lot to do for my simple task. > > > > > the repository structure looks as follows: > > > > > Projekt > > > > > - cpp-src > > > - some.cpp > > > - some.h > > > - lib-src > > > - CPPLib.hs > > > - program-src > > > - program.hs > > > - project.cabal > > > > > And my (currently failing) project.cabal the following: > > > > > > > > cabal-version: 3.0 > > > name: cpp_lib > > > [...] > > > library > > > exposed-modules: CPPLib > > > other-extensions: ForeignFunctionInterface > > > build-depends: base > > > hs-source-dirs: lib-src > > > default-language: Haskell2010 > > > include-dirs: ./cpp-src > > > cxx-sources: ./cpp-src/some.cpp > > > install-includes: ./cpp-src/some.h > > > > > > > > executable CPPApp > > > main-is: program.hs > > > default-language: Haskell2010 > > > build-depends: HaskellForeignCPP, > > > base > > > hs-source-dirs: program-src > > > > > > > > The some.cpp is trivial for this case lets assume its a function > > > > > > > multiply :: Int -> Int -> Int, and both .cpp and .h are well-formed and > > don't have further dependencies. > > > > > > > > > > > > > > > The library compiles fine, but when building the executable it fails > > > telling me > > > > > collect2: error: ld returned 1 exit status > > > `gcc' failed in phase`Linker'. (Exit code: 1) > > > > > Can someone help me out? > > > I find very little documentation on this topic. > > > > > I know there is Inline-CPP which would help as well, but I just very > > > much like the idea of having a nice separate file and interface for > > > modularity. > > > > > best > > > Leonhard > > > -------------- next part -------------- > > > An HTML attachment was scrubbed... > > > URL: > > > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.html > > > -------------- next part -------------- > > > A non-text attachment was scrubbed... > > > Name: signature.asc > > > Type: application/pgp-signature > > > Size: 477 bytes > > > Desc: OpenPGP digital signature > > > URL: > > > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.sig > > > > > -- > > > > > Subject: Digest Footer > > > > > Beginners mailing list > > > Beginners at haskell.org > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > > > > > > > > > > > > > > > > > End of Beginners Digest, Vol 143, Issue 12 > > > > -------------- next part -------------- > > A non-text attachment was scrubbed... > > Name: signature.asc > > Type: application/pgp-signature > > Size: 477 bytes > > Desc: OpenPGP digital signature > > URL: < > > http://mail.haskell.org/pipermail/beginners/attachments/20200525/0e889731/attachment-0001.sig > > > > > > > > > Message: 2 > > Date: Mon, 25 May 2020 16:45:09 -0700 > > From: 鲍凯文 traqueofziche at gmail.com > > To: beginners at haskell.org > > Subject: Re: [Haskell-beginners] Linking C++ in Cabal > > Message-ID: > > > XNqEdg3ox2Q at mail.gmail.com> > > Content-Type: text/plain; charset="utf-8" > > Hi, > > Would it be possible to upload your full repo somewhere so people could see > > everything and possibly reproduce this? > > Thanks, > > toz > > On Mon, May 25, 2020 at 5:03 AM beginners-request at haskell.org wrote: > > > > > Send Beginners mailing list submissions to > > > beginners at haskell.org > > > To subscribe or unsubscribe via the World Wide Web, visit > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > or, via email, send a message with subject or body 'help' to > > > beginners-request at haskell.org > > > You can reach the person managing the list at > > > beginners-owner at haskell.org > > > When replying, please edit your Subject line so it is more specific > > > than "Re: Contents of Beginners digest..." > > > Today's Topics: > > > > > > 1. Linking C++ in Cabal (Leonhard Applis) > > > > > > Message: 1 > > > Date: Sun, 24 May 2020 16:30:22 +0000 > > > From: Leonhard Applis Leonhard.Applis at protonmail.com > > > To: "beginners at haskell.org" beginners at haskell.org > > > Subject: [Haskell-beginners] Linking C++ in Cabal > > > Message-ID: > > > > <51wOfngyX74dYjJRw6hibqw07vGHvvSYPD_f3f2-_F7hG0k0GwWf2Xv4g7LyeZNyn_vR28s6GIbd3e-78_TapNIEo_tJZ-2fTViOmkQYOnM=@ > > > > > protonmail.com> > > > Content-Type: text/plain; charset="utf-8" > > > Hello, > > > I want to use a foreign C++ Function in a Haskell Library, and the > > > Library > > > in a Haskell Program. > > > The C++ function is separate in a file and I have a header file. > > > I made a minimal reproducing repository. > > > The closes I have found is this repository which wraps the c++ in c and > > > makes a full library, needing a makefile etc. > > > So while I think I'd get it working like that, it looks to be quite a lot > > > to do for my simple task. > > > the repository structure looks as follows: > > > Projekt > > > > > > - cpp-src > > > > > > - some.cpp > > > > > > - some.h > > > > > > - lib-src > > > > > > - CPPLib.hs > > > > > > - program-src > > > > > > - program.hs > > > > > > - project.cabal > > > > > > > > > And my (currently failing) project.cabal the following: > > > cabal-version: 3.0 > > > name: cpp_lib > > > [...] > > > library > > > exposed-modules: CPPLib > > > other-extensions: ForeignFunctionInterface > > > build-depends: base > > > hs-source-dirs: lib-src > > > default-language: Haskell2010 > > > include-dirs: ./cpp-src > > > cxx-sources: ./cpp-src/some.cpp > > > install-includes: ./cpp-src/some.h > > > executable CPPApp > > > main-is: program.hs > > > default-language: Haskell2010 > > > build-depends: HaskellForeignCPP, > > > base > > > hs-source-dirs: program-src > > > The some.cpp is trivial for this case lets assume its a function multiply > > > :: Int -> Int -> Int, and both .cpp and .h are well-formed and don't have > > > further dependencies. > > > The library compiles fine, but when building the executable it fails > > > telling me > > > collect2: error: ld returned 1 exit status > > > `gcc' failed in phase`Linker'. (Exit code: 1) > > > Can someone help me out? > > > I find very little documentation on this topic. > > > I know there is Inline-CPP which would help as well, but I just very much > > > like the idea of having a nice separate file and interface for > > > modularity. > > > best > > > Leonhard > > > -------------- next part -------------- > > > An HTML attachment was scrubbed... > > > URL: < > > > > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.html > > > > > > > > > > > > -------------- next part -------------- > > > A non-text attachment was scrubbed... > > > Name: signature.asc > > > Type: application/pgp-signature > > > Size: 477 bytes > > > Desc: OpenPGP digital signature > > > URL: < > > > > http://mail.haskell.org/pipermail/beginners/attachments/20200524/9019cbc0/attachment-0001.sig > > > > > > > > > > > > Subject: Digest Footer > > > > > > Beginners mailing list > > > Beginners at haskell.org > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > > > End of Beginners Digest, Vol 143, Issue 12 > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > > http://mail.haskell.org/pipermail/beginners/attachments/20200525/002f0b3f/attachment-0001.html > > > > > > > > > Subject: Digest Footer > > > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > End of Beginners Digest, Vol 143, Issue 13 > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: http://mail.haskell.org/pipermail/beginners/attachments/20200526/4607f2a5/attachment.html > > -- > > Subject: Digest Footer > > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > --------------------------------------------------------------------------------------------------------- > > End of Beginners Digest, Vol 143, Issue 14 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 477 bytes Desc: OpenPGP digital signature URL: From alexander at chenjia.nl Wed May 27 18:55:55 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Wed, 27 May 2020 20:55:55 +0200 (CEST) Subject: [Haskell-beginners] Foldl Message-ID: <399792716.37235.1590605755253@ichabod.co-bxl> Hi, I guess it's time to get acquainted with foldr and foldl. prelude>xs = [1..5] ++ undefined prelude> foldr const 0 xs 1 I assume it goes something like this: ( 1 `const`(2 `const`(3 `const`(4 `const`(5 `const`(undefined `const` 0))))))                                                               ( 5 `const` undefined)                                                (4 `const` 5)                                     (3 `const` 4)                 ( 2 `const` 3) (1 `const`2) = 1 ======================================================================== What i don't get is the opposite: prelude> foldl const 0 xs error in my mind this should go like this:  ((((((0`const`1)`const` 2) `const` 3 )`const` 4)`const`  5) `const` undefined)                     (0 `const`2)                                       (0`const` 3)                                                                   ( 0`const`4)                                                                        (0`const` 5)                                                                                       (0 `const` undefined ) = 0 I have been told that the main difference between foldl and foldr is that foldl needs to evaluate the whole spline before it continues. And i guess that has something to do with it. What I don't understand is WHY foldl need to do this and foldr doesn't. thanks in advance! best, -------------- next part -------------- An HTML attachment was scrubbed... URL: From tonymorris at gmail.com Wed May 27 21:33:58 2020 From: tonymorris at gmail.com (Tony Morris) Date: Thu, 28 May 2020 07:33:58 +1000 Subject: [Haskell-beginners] Foldl In-Reply-To: <399792716.37235.1590605755253@ichabod.co-bxl> References: <399792716.37235.1590605755253@ichabod.co-bxl> Message-ID: foldl does a loop, foldr does constructor replacement https://www.youtube.com/watch?v=GPwtT31zKRY On 5/28/20 4:55 AM, Alexander Chen wrote: > Hi, > > I guess it's time to get acquainted with foldr and foldl. > > *prelude>xs = [1..5] ++ undefined* > *prelude> foldr const 0 xs* > *1* > > I assume it goes something like this: > > ( 1 `const`(2 `const`(3 `const`(4 `const`(5 `const`(undefined `const` > 0)))))) >                                                               ( > 5 `const` undefined) >                                                (4 `const` 5)     >                                 (3 `const` 4) >                 ( 2 `const` 3) > (1 `const`2) > = 1 > > ======================================================================== > > > What i don't get is the opposite: > > *prelude> foldl const 0 xs* > *error* > > > in my mind this should go like this:  > ((((((0`const`1)`const` 2) `const` 3 )`const` 4)`const`  5) > `const` undefined) >                     (0 `const`2) >                                       (0`const` 3)             >                                                       ( 0`const`4) >                                                                       >  (0`const` 5) >                                                                         >               (0 `const` undefined ) > = 0 > > > > I have been told that the main difference between foldl and foldr is > that foldl needs to evaluate the whole spline before it continues. And i > guess that has something to do with it. What I don't understand is WHY > foldl need to do this and foldr doesn't. > > > thanks in advance! > > best, > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From alexander at chenjia.nl Fri May 29 05:22:20 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Fri, 29 May 2020 07:22:20 +0200 (CEST) Subject: [Haskell-beginners] Foldl In-Reply-To: References: <399792716.37235.1590605755253@ichabod.co-bxl> Message-ID: <1003915704.58782.1590729740929@ichabod.co-bxl> May 27, 2020 11:33:58 PM CEST Tony Morris wrote:foldl does a loop, foldr does constructor replacement https://www.youtube.com/watch?v=GPwtT31zKRY On 5/28/20 4:55 AM, Alexander Chen wrote: > Hi, > > I guess it's time to get acquainted with foldr and foldl. > > *prelude>xs = [1..5] ++ undefined* > *prelude> foldr const 0 xs* > 1 > > I assume it goes something like this: > > ( 1 `const`(2 `const`(3 `const`(4 `const`(5 `const`(undefined `const` > 0)))))) >                                                               ( > 5 `const` undefined) >                                                (4 `const` 5)     >                                 (3 `const` 4) >                 ( 2 `const` 3) > (1 `const`2) > = 1 > > ======================================================================== > > > What i don't get is the opposite: > > *prelude> foldl const 0 xs* > error > > > in my mind this should go like this:  > ((((((0`const`1)`const` 2) `const` 3 )`const` 4)`const`  5) > `const` undefined) >                     (0 `const`2) >                                       (0`const` 3)             >                                                       ( 0`const`4) >                                                                       >  (0`const` 5) >                                                                         >               (0 `const` undefined ) > = 0 > > > > I have been told that the main difference between foldl and foldr is > that foldl needs to evaluate the whole spline before it continues. And i > guess that has something to do with it. What I don't understand is WHY > foldl need to do this and foldr doesn't. > > > thanks in advance! > > best, > > _______________________________________________ > 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 alexander at chenjia.nl Fri May 29 09:55:31 2020 From: alexander at chenjia.nl (Alexander Chen) Date: Fri, 29 May 2020 11:55:31 +0200 (CEST) Subject: [Haskell-beginners] data type Message-ID: <615928762.72602.1590746131235@ichabod.co-bxl> import Data.Time data DatabaseItem = DbString String                   | DbNumber Integer                   | DbDate   UTCTime                   deriving  (Eq, Ord, Show) theDatabase :: [DatabaseItem] theDatabase =     [ DbDate (UTCTime              (fromGregorian 1911 5 1)       (secondsToDiffTime 34250))     , DbNumber 9001     , DbString "Hello, world!"     , DbDate (UTCTime              (fromGregorian 1921 5 1)              (secondsToDiffTime 34123))     ] My question: I want to get the UTCTime. So,  thisFunction :: [DatabaseItem] -> [UTCTime] I don't need the answer but more the intuition (a link to a youtube etc. is also possible) how to handle these types of situations. Because i keep trying to think in terms of key:values (Python,Julia) which doesn't seem the right paradigm to approach this. thanks in advance! best, -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Fri May 29 10:03:48 2020 From: fa-ml at ariis.it (Francesco Ariis) Date: Fri, 29 May 2020 12:03:48 +0200 Subject: [Haskell-beginners] data type In-Reply-To: <615928762.72602.1590746131235@ichabod.co-bxl> References: <615928762.72602.1590746131235@ichabod.co-bxl> Message-ID: <20200529100348.GA20444@extensa> Hello Alexander. Il 29 maggio 2020 alle 11:55 Alexander Chen ha scritto: > import Data.Time > > data DatabaseItem = DbString String >                   | DbNumber Integer >                   | DbDate   UTCTime >                   deriving  (Eq, Ord, Show) > > theDatabase :: [DatabaseItem] > theDatabase = >     [ DbDate (UTCTime >              (fromGregorian 1911 5 1) >       (secondsToDiffTime 34250)) >     , DbNumber 9001 >     , DbString "Hello, world!" >     , DbDate (UTCTime >              (fromGregorian 1921 5 1) >              (secondsToDiffTime 34123)) >     ] > > My question: > > I want to get the UTCTime. > > So,  thisFunction :: [DatabaseItem] -> [UTCTime] This is an excellent first step. A good candidate function is `map` λ> :t map map :: (a -> b) -> [a] -> [b] and if we fill in the arguments we are sure of and leave the rest out, ghc will — on reload/recompile — tell us what is missing. E.g: thisFunction :: [DatabaseItem] -> [UTCTime] thisFunction ds = map _ ds will lead to • Found hole: _ :: DatabaseItem -> UTCTime • In the first argument of ‘map’, namely ‘_’ Can you write a function with `DatabaseItem -> UTCTime` signature? From julytreee at gmail.com Fri May 29 10:35:18 2020 From: julytreee at gmail.com (Treee July) Date: Fri, 29 May 2020 18:35:18 +0800 Subject: [Haskell-beginners] How to change base version easily? Message-ID: Hello, I installed the latest version of ghc, which caused one of my packages does not satisfy the constraint of the version. I just wondering if there exists a convenient way to degrade the version of the base. I use Arch Linux, which is not easy to install an elder version. Thanks, July -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Fri May 29 10:56:42 2020 From: fa-ml at ariis.it (Francesco Ariis) Date: Fri, 29 May 2020 12:56:42 +0200 Subject: [Haskell-beginners] How to change base version easily? In-Reply-To: References: Message-ID: <20200529105642.GA15236@extensa> Hello July, Il 29 maggio 2020 alle 18:35 Treee July ha scritto: > Hello, > I installed the latest version of ghc, which caused one of my packages does > not satisfy the constraint of the version. I just wondering if there exists > a convenient way to degrade the version of the base. I use Arch Linux, > which is not easy to install an elder version. if you are using cabal, --allow-newer can ease some of the pain. Failing that, -w will work — but you need to download and locally install the appropriate ghc first. Let us know if that’s enough From sylvain at haskus.fr Fri May 29 12:00:00 2020 From: sylvain at haskus.fr (Sylvain Henry) Date: Fri, 29 May 2020 14:00:00 +0200 Subject: [Haskell-beginners] How to change base version easily? In-Reply-To: <20200529105642.GA15236@extensa> References: <20200529105642.GA15236@extensa> Message-ID: <6305cedc-8333-a228-10f7-38a8c2869f8a@haskus.fr> Using haskell packages provided by ArchLinux is a pain (cf https://wiki.archlinux.org/index.php/Haskell). You have to tweak ~/.cabal/config, etc. I would recommend using `stack` as it manages ghc installations itself. You could also use ghcup+cabal-install. Cheers, Sylvain On 29/05/2020 12:56, Francesco Ariis wrote: > Hello July, > > Il 29 maggio 2020 alle 18:35 Treee July ha scritto: >> Hello, >> I installed the latest version of ghc, which caused one of my packages does >> not satisfy the constraint of the version. I just wondering if there exists >> a convenient way to degrade the version of the base. I use Arch Linux, >> which is not easy to install an elder version. > if you are using cabal, --allow-newer can ease some of the pain. Failing > that, -w will work — but you need to download and locally install the > appropriate ghc first. > Let us know if that’s enough > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners From julytreee at gmail.com Sat May 30 10:34:45 2020 From: julytreee at gmail.com (Treee July) Date: Sat, 30 May 2020 18:34:45 +0800 Subject: [Haskell-beginners] How to change base version easily? Message-ID: > > Hello July, > Il 29 maggio 2020 alle 18:35 Treee July ha scritto: > > Hello, > > I installed the latest version of ghc, which caused one of my packages > does > > not satisfy the constraint of the version. I just wondering if there > exists > > a convenient way to degrade the version of the base. I use Arch Linux, > > which is not easy to install an elder version. > if you are using cabal, --allow-newer can ease some of the pain. Failing > that, -w will work — but you need to download and locally install the > appropriate ghc first. > Let us know if that’s enough Hi Francesco, I'm glad to tell you that your suggestion about --allow-newer works on my machine! But I still have some trouble with running correctly on Arch Linux(That's really annoying), maybe I can solve it later. Thank you again!. Best, July -------------- next part -------------- An HTML attachment was scrubbed... URL: From julytreee at gmail.com Sat May 30 10:36:52 2020 From: julytreee at gmail.com (Treee July) Date: Sat, 30 May 2020 18:36:52 +0800 Subject: [Haskell-beginners] How to change base version easily? (Sylvain Henry) Message-ID: Hello Sylvain, I am not familiar with stack at all, maybe I'll try it if I have no more solutions. Thank you. Best, July -------------- next part -------------- An HTML attachment was scrubbed... URL: