
Hi all, In Lua I could do something like this: -- initialize empty table P = {} P.a = "bla1" P.b = "bla2" and so on. Now I can refer to each value by name, and I also can easily iterate over the table P. How can I do something similar in Haskell. Note: I do want only write each variable one time (or two times if I count the type definition). I thought about: data P = P { a :: String, b :: String } Then I have one definition pval = P { a = "bla1", b = "bla2" } Now I could refer to each val easily, e.g. a pval. However, I don't see that I could iterate over the members of pval. It there a way to do what I want without defining a list like this? pls p = [ (a p), (b p)] Perhaps a comletely different way? -- Manfred

Hey Manfred.
Take a look at "Record Syntax" topic of the book "Learn you a Haskell
for great good". It looks like what you want.
http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-synt...
Thiago.
2011/8/7 Manfred Lotz
Hi all, In Lua I could do something like this:
-- initialize empty table P = {}
P.a = "bla1" P.b = "bla2"
and so on.
Now I can refer to each value by name, and I also can easily iterate over the table P.
How can I do something similar in Haskell. Note: I do want only write each variable one time (or two times if I count the type definition).
I thought about:
data P = P { a :: String, b :: String }
Then I have one definition
pval = P { a = "bla1", b = "bla2" }
Now I could refer to each val easily, e.g. a pval. However, I don't see that I could iterate over the members of pval.
It there a way to do what I want without defining a list like this? pls p = [ (a p), (b p)]
Perhaps a comletely different way?
-- Manfred
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I was just glancing through that chapter when I saw the phrase
"Paamayim Nekudotayim." I was most certainly not expecting Hebrew
phrases to pop up here. Has this phrase somehow made it into a larger
circle without my knowing, or is there some explanation out there as
to why it's used in LYAH?
On Sun, Aug 7, 2011 at 4:10 PM, Thiago Negri
Hey Manfred.
Take a look at "Record Syntax" topic of the book "Learn you a Haskell for great good". It looks like what you want.
http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-synt...
Thiago.
2011/8/7 Manfred Lotz
: Hi all, In Lua I could do something like this:
-- initialize empty table P = {}
P.a = "bla1" P.b = "bla2"
and so on.
Now I can refer to each value by name, and I also can easily iterate over the table P.
How can I do something similar in Haskell. Note: I do want only write each variable one time (or two times if I count the type definition).
I thought about:
data P = P { a :: String, b :: String }
Then I have one definition
pval = P { a = "bla1", b = "bla2" }
Now I could refer to each val easily, e.g. a pval. However, I don't see that I could iterate over the members of pval.
It there a way to do what I want without defining a list like this? pls p = [ (a p), (b p)]
Perhaps a comletely different way?
-- Manfred
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Sorry, forgot to explain the phrase. In Hebrew, the ending "ayim" is
the dual form, used often for limbs (yadayim = hands, raglayim = feet,
etc). "Paam" means "time", and "paamayim" means "two times". "Nekuda"
means dot/period, and "nekudotayim" means two dots (== colon).
Paamayim Nekudotayim therefore is double-double dots, or two colons.
On Sun, Aug 7, 2011 at 4:17 PM, Michael Snoyman
I was just glancing through that chapter when I saw the phrase "Paamayim Nekudotayim." I was most certainly not expecting Hebrew phrases to pop up here. Has this phrase somehow made it into a larger circle without my knowing, or is there some explanation out there as to why it's used in LYAH?
On Sun, Aug 7, 2011 at 4:10 PM, Thiago Negri
wrote: Hey Manfred.
Take a look at "Record Syntax" topic of the book "Learn you a Haskell for great good". It looks like what you want.
http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-synt...
Thiago.
2011/8/7 Manfred Lotz
: Hi all, In Lua I could do something like this:
-- initialize empty table P = {}
P.a = "bla1" P.b = "bla2"
and so on.
Now I can refer to each value by name, and I also can easily iterate over the table P.
How can I do something similar in Haskell. Note: I do want only write each variable one time (or two times if I count the type definition).
I thought about:
data P = P { a :: String, b :: String }
Then I have one definition
pval = P { a = "bla1", b = "bla2" }
Now I could refer to each val easily, e.g. a pval. However, I don't see that I could iterate over the members of pval.
It there a way to do what I want without defining a list like this? pls p = [ (a p), (b p)]
Perhaps a comletely different way?
-- Manfred
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Sunday 07 August 2011, 15:19:41, Michael Snoyman wrote:
Sorry, forgot to explain the phrase. In Hebrew, the ending "ayim" is the dual form, used often for limbs (yadayim = hands, raglayim = feet, etc). "Paam" means "time", and "paamayim" means "two times". "Nekuda" means dot/period, and "nekudotayim" means two dots (== colon). Paamayim Nekudotayim therefore is double-double dots, or two colons.
On Sun, Aug 7, 2011 at 4:17 PM, Michael Snoyman
wrote: I was just glancing through that chapter when I saw the phrase "Paamayim Nekudotayim." I was most certainly not expecting Hebrew phrases to pop up here. Has this phrase somehow made it into a larger circle without my knowing, or is there some explanation out there as to why it's used in LYAH?
My guess: it's a reference to PHP, which, as far as I know, calls its scope resolution operator thus (and confused the heck out of many people with "Syntax error, unexpected T PAAMAYIM NEKUDOTAYIM") and thus made this phrase known in wider circles of goyim too.

On Sun, Aug 7, 2011 at 4:37 PM, Daniel Fischer
On Sunday 07 August 2011, 15:19:41, Michael Snoyman wrote:
Sorry, forgot to explain the phrase. In Hebrew, the ending "ayim" is the dual form, used often for limbs (yadayim = hands, raglayim = feet, etc). "Paam" means "time", and "paamayim" means "two times". "Nekuda" means dot/period, and "nekudotayim" means two dots (== colon). Paamayim Nekudotayim therefore is double-double dots, or two colons.
On Sun, Aug 7, 2011 at 4:17 PM, Michael Snoyman
wrote: I was just glancing through that chapter when I saw the phrase "Paamayim Nekudotayim." I was most certainly not expecting Hebrew phrases to pop up here. Has this phrase somehow made it into a larger circle without my knowing, or is there some explanation out there as to why it's used in LYAH?
My guess: it's a reference to PHP, which, as far as I know, calls its scope resolution operator thus (and confused the heck out of many people with "Syntax error, unexpected T PAAMAYIM NEKUDOTAYIM") and thus made this phrase known in wider circles of goyim too.
Ahhh.... thanks for the explanation.

On Sun, 7 Aug 2011 10:10:04 -0300
Thiago Negri
Hey Manfred.
Take a look at "Record Syntax" topic of the book "Learn you a Haskell for great good". It looks like what you want.
http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-synt...
Thanks for pointing me to this. At least it shows a nice way do define records without the need to name the members.
pval = P { a = "bla1", b = "bla2" }
This could be then pval = P "bla1" "bla2", however it doesn't give me map over the member of the record which I want because I have some 15 members of such a record. -- Manfred

Manfred Lotz
In Lua I could do something like this:
-- initialize empty table P = {}
P.a = "bla1" P.b = "bla2"
and so on.
Now I can refer to each value by name, and I also can easily iterate over the table P.
How can I do something similar in Haskell. Note: I do want only write each variable one time (or two times if I count the type definition).
I think you're not actually asking for record types at all, because that doesn't really fit into Haskell's type system. Rather you may want to have a look at maps. See the Data.Map module. Those are dictionaries with fast update and lookup as well as traversal operations. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

On Sun, 7 Aug 2011 15:21:13 +0200
Ertugrul Soeylemez
Manfred Lotz
wrote: In Lua I could do something like this:
-- initialize empty table P = {}
P.a = "bla1" P.b = "bla2"
and so on.
Now I can refer to each value by name, and I also can easily iterate over the table P.
How can I do something similar in Haskell. Note: I do want only write each variable one time (or two times if I count the type definition).
I think you're not actually asking for record types at all, because that doesn't really fit into Haskell's type system. Rather you may want to have a look at maps. See the Data.Map module. Those are dictionaries with fast update and lookup as well as traversal operations.
Hmm, not quite sure I'm understanding why Data.Map would help. What I want to have is something like the following without the verboseness of it: -- this is a minimal example. -- Assume I would have some 15 such values. a = "bla" b = "bla2" valList = [ a, b ] Now in my program on the one hand I want to do something with all values, thus: map doSomething valList On the other hand I frequently want use single values in my program, like e.g.: let x = "suffix " ++ a What I don't want to do is to write a definition like valList because if I add a new value I have to remind myself not to forget to add it to valList too. -- Manfred -- Manfred

On Aug 7, 2011, at 11:07 AM, Manfred Lotz wrote:
What I don't want to do is to write a definition like valList because if I add a new value I have to remind myself not to forget to add it to valList too.
Hi, Manfred. I think we are having difficulty understanding what you are try to do. Since, you are worried about conciseness, why not write out the Haskell program that shows what you want to do without worrying about conciseness. Then we can look for opportunities to improve it. ____________________ David Place Owner, Panpipes Ho! LLC http://panpipesho.com d@vidplace.com

Hi David,
On Sun, 7 Aug 2011 11:19:21 -0400
David Place
On Aug 7, 2011, at 11:07 AM, Manfred Lotz wrote:
What I don't want to do is to write a definition like valList because if I add a new value I have to remind myself not to forget to add it to valList too.
Hi, Manfred.
I think we are having difficulty understanding what you are try to do. Since, you are worried about conciseness, why not write out the Haskell program that shows what you want to do without worrying about conciseness. Then we can look for opportunities to improve it.
You may be right. Here is what I want to do. I have some 15 directories as Strings, where I want to do certain actions like to create those directories, or doing some other things to all of those directories. For doing this something like this would be good (for the sake of simplicity I do not write down all 15 entries) dirLst = [ "somedir", "otherdir" ] main = do map makeDir dirLst ... Later on in the program I would need those directorie names to create (depending upon the context) new pathnames. Now something like this would be good. -- In my program instead of d1,...,d15 -- I use meaningful names of course. d1 = "somedir" ... d15 = "otherdir" doSomething fls = do let pathname = d1 ++ "/bin" copyFiles2bin fls pathname ... I would like to combine both approaches in a concise (from a typing point of view) way. This I don't like d1 = "somedir" ... d15 = "otherdir" dirLst = [ d1, d15] because then I have to write names d1, ..., d15 two times in order to get my definitions right. I'm looking for a more elegant way doing this. Hope this is a bit clearer what I'm after. -- Thanks, Manfred

On Aug 7, 2011, at 12:36 PM, Manfred Lotz wrote:
because then I have to write names d1, ..., d15 two times in order to get my definitions right. I'm looking for a more elegant way doing this.
Hope this is a bit clearer what I'm after.
Yes, thank you, that is quite clear. I think that is the best you can do in Haskell. I really don't see it as inelegant at all. You define the variables d1 through d15 and then dirList is a function of those definitions. You type d1 once for its definition and next for its use. You would like to combine the two activities? Something like this perhaps? dirLst = [d1 = "somedir", d15 = "otherdir"] How would these variables be scoped? ____________________ David Place Owner, Panpipes Ho! LLC http://panpipesho.com d@vidplace.com

On Sun, 7 Aug 2011 12:52:59 -0400
David Place
On Aug 7, 2011, at 12:36 PM, Manfred Lotz wrote:
because then I have to write names d1, ..., d15 two times in order to get my definitions right. I'm looking for a more elegant way doing this.
Hope this is a bit clearer what I'm after.
Yes, thank you, that is quite clear. I think that is the best you can do in Haskell. I really don't see it as inelegant at all. You define the variables d1 through d15 and then dirList is a function of those definitions. You type d1 once for its definition and next for its use. You would like to combine the two activities? Something like this perhaps? dirLst = [d1 = "somedir", d15 = "otherdir"]
If this were possible that would be fine. When trying to compile this however I get: parse error on input `=' -- Manfred

Manfred Lotz
I have some 15 directories as Strings, where I want to do certain actions like to create those directories, or doing some other things to all of those directories.
For doing this something like this would be good (for the sake of simplicity I do not write down all 15 entries)
dirLst = [ "somedir", "otherdir" ]
main = do map makeDir dirLst ...
This is possible in Haskell using the mapM_ function, but it doesn't really solve your problem. What you need is a foldable data structure, which gives its entries names. As suggested earlier, Data.Map gives you such a structure. You can define a custom index type like this: data AppDir = ConfigAppDir | DataAppDir | OtherAppDir deriving Ord Then you can create a map from AppDir to a string: import Data.Map (Map) type AppDirs = Map AppDir FilePath This is a foldable data structure. Instead of mapM_ from the Prelude you can now use mapM_ or forM_ from Data.Foldable. To access individual directories you can either use safe lookups or unsafe lookups: import Data.Map (Map, (!), lookup) lookup ConfigAppDir myDirs myDirs ! ConfigAppDir The former is the safe variant giving you a Maybe String, while the latter is the unsafe variant, which throws an exception, if the directory in question is not present. Another possibility, though more verbose, but cleaner, is to define your own data structure and define a Foldable instance for it: data AppDirs a = AppDirs { configAppDir :: a, dataAppDir :: a, otherAppDir :: a } instance Foldable AppDirs where foldr f dirs = mconcat . map f . map ($ dirs) $ [configAppDir, dataAppDir, otherAppDir] I think, the Map solution is cleaner. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

On Sun, 7 Aug 2011 18:55:37 +0200
Ertugrul Soeylemez
This is possible in Haskell using the mapM_ function, but it doesn't really solve your problem. What you need is a foldable data structure, which gives its entries names. As suggested earlier, Data.Map gives you such a structure. You can define a custom index type like this:
data AppDir = ConfigAppDir | DataAppDir | OtherAppDir deriving Ord
Then you can create a map from AppDir to a string:
import Data.Map (Map)
type AppDirs = Map AppDir FilePath
This is a foldable data structure. Instead of mapM_ from the Prelude you can now use mapM_ or forM_ from Data.Foldable. To access individual directories you can either use safe lookups or unsafe lookups:
import Data.Map (Map, (!), lookup)
lookup ConfigAppDir myDirs myDirs ! ConfigAppDir
This is the solution I like. I have to accept that here I cannot reach the conciseness of which might be due to Haskell being strongly typed.
The former is the safe variant giving you a Maybe String, while the latter is the unsafe variant, which throws an exception, if the directory in question is not present.
Is the latter one really unsafe? I'm not quite sure how to code something that the compiler accepts and crashes at runtime because mydirs :: Map AppDir FilePath and I would believe that the compiler would detect if the values after the ! is not from AppDir. -- Manfred

On Aug 7, 2011, at 3:55 PM, Manfred Lotz wrote:
import Data.Map (Map, (!), lookup)
lookup ConfigAppDir myDirs myDirs ! ConfigAppDir
This is the solution I like. I have to accept that here I cannot reach the conciseness of which might be due to Haskell being strongly typed.
In your original note, you mentioned that you have a small number of entries in your list of directories. If so, you might find that association lists work just fine for you without needing to import Data.Map.
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.htm...

On Sun, 7 Aug 2011 16:27:11 -0400
David Place
On Aug 7, 2011, at 3:55 PM, Manfred Lotz wrote:
import Data.Map (Map, (!), lookup)
lookup ConfigAppDir myDirs myDirs ! ConfigAppDir
This is the solution I like. I have to accept that here I cannot reach the conciseness of which might be due to Haskell being strongly typed.
In your original note, you mentioned that you have a small number of entries in your list of directories. If so, you might find that association lists work just fine for you without needing to import Data.Map.
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.htm...
Yes, this is true. Assoc lists would do just fine. What I found is that there is no real concise way of defining something like this in Haskell. The shortest definition I found is this: ([cAppDir, dAppDir, oAppDir],dirlist) = (l,l) where l = [ "app/config", "app/data", "app/other"] which is ok. However, here I must be careful (when having 15 directories or so) to keep the sequence of variable names in line with the sequence of directories in l. Additionally, if I have a different number of directories in l than I have variable names in the beginning of the definition list (cAppDir aso) I would only notice at runtime when accessing any of those variables. That is why a data type and then something like an assoc list is safer to use (but more verbose). -- Manfred

Manfred Lotz
import Data.Map (Map, (!), lookup)
lookup ConfigAppDir myDirs myDirs ! ConfigAppDir
This is the solution I like. I have to accept that here I cannot reach the conciseness of which might be due to Haskell being strongly typed.
Note that likely this solution is no different from the Lua solution. You are just coding directly for what you have syntactic sugar in Lua. After all the interpreter keeps a list (or more likely a map) of variables and just does indexing and mapping. Also I don't find it terribly less concise. It's just the overwhelming import stuff, which makes the code larger in such a small example.
The former is the safe variant giving you a Maybe String, while the latter is the unsafe variant, which throws an exception, if the directory in question is not present.
Is the latter one really unsafe? I'm not quite sure how to code something that the compiler accepts and crashes at runtime because mydirs :: Map AppDir FilePath and I would believe that the compiler would detect if the values after the ! is not from AppDir.
The compiler cannot detect that, because you are essentially writing a mini-interpreter. Just like Lua cannot predetect the absence of a variable at parse time. To be safe you should use lookup: lookup :: Ord k => k -> Map k a -> Maybe a This isn't too bad, because Maybe is a monad, and you have convenient combinators like 'maybe': maybe (putStrLn "Configuration directory not specified") doSomethingWithConfigDir myAppDirs Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

On Mon, 8 Aug 2011 09:48:11 +0200
Ertugrul Soeylemez
Manfred Lotz
wrote: import Data.Map (Map, (!), lookup)
lookup ConfigAppDir myDirs myDirs ! ConfigAppDir
This is the solution I like. I have to accept that here I cannot reach the conciseness of which might be due to Haskell being strongly typed.
Note that likely this solution is no different from the Lua solution. You are just coding directly for what you have syntactic sugar in Lua.
Yes, of course. That is syntactic sugar in Lua.
After all the interpreter keeps a list (or more likely a map) of variables and just does indexing and mapping.
Sure.
Also I don't find it terribly less concise. It's just the overwhelming import stuff, which makes the code larger in such a small example.
Yeah, I can live with that.
The former is the safe variant giving you a Maybe String, while the latter is the unsafe variant, which throws an exception, if the directory in question is not present.
Is the latter one really unsafe? I'm not quite sure how to code something that the compiler accepts and crashes at runtime because mydirs :: Map AppDir FilePath and I would believe that the compiler would detect if the values after the ! is not from AppDir.
The compiler cannot detect that, because you are essentially writing a mini-interpreter. Just like Lua cannot predetect the absence of a variable at parse time. To be safe you should use lookup:
lookup :: Ord k => k -> Map k a -> Maybe a
This isn't too bad, because Maybe is a monad, and you have convenient combinators like 'maybe':
maybe (putStrLn "Configuration directory not specified") doSomethingWithConfigDir myAppDirs
Thanks much for the explanations you gave me (not only this reply). That was some new stuff for me as a Haskell beginner. -- Manfred

Sorry, I haven't read all the replies so I don't know if you have completely described the problem you're trying to solve; however, it might be better for people in future to say they want O(1) for insertions, O(lg n) for searching, etc. If they don't want to completely describe what their problem is. -- -- Regards, KC

On Mon, 8 Aug 2011 07:31:32 -0700
KC
Sorry, I haven't read all the replies so I don't know if you have completely described the problem you're trying to solve; however, it might be better for people in future to say they want O(1) for insertions, O(lg n) for searching, etc.
If they don't want to completely describe what their problem is.
Well, it might be that this time the description of my problem was not fully satisfying (at least in the beginning) for others being able to answer me. However, I have to say the help I got was great (as is usually the case in Haskell news groups). Thanks to all who replied. I feel my question being answered fully. -- Thanks again, Manfred

2011/8/7 Manfred Lotz
Hi David,
On Sun, 7 Aug 2011 11:19:21 -0400 David Place
wrote: On Aug 7, 2011, at 11:07 AM, Manfred Lotz wrote:
What I don't want to do is to write a definition like valList because if I add a new value I have to remind myself not to forget to add it to valList too.
Hi, Manfred.
I think we are having difficulty understanding what you are try to do. Since, you are worried about conciseness, why not write out the Haskell program that shows what you want to do without worrying about conciseness. Then we can look for opportunities to improve it.
You may be right. Here is what I want to do.
I have some 15 directories as Strings, where I want to do certain actions like to create those directories, or doing some other things to all of those directories.
For doing this something like this would be good (for the sake of simplicity I do not write down all 15 entries)
dirLst = [ "somedir", "otherdir" ]
main = do map makeDir dirLst ...
Later on in the program I would need those directorie names to create (depending upon the context) new pathnames. Now something like this would be good.
-- In my program instead of d1,...,d15 -- I use meaningful names of course. d1 = "somedir" ... d15 = "otherdir"
doSomething fls = do let pathname = d1 ++ "/bin" copyFiles2bin fls pathname
...
Why not dirLst = [ ("somedir",doSomething fls), ("otherdir",doNothing), ("otherdir2",doNothing), ("otherdir3",doTheDance), ("otherdir4",doNothing) ("otherdir4",doDeeDooDa fls2 fls3) ] doSomething fls d = do let pathname = d > "bin" copyFiles2bin fls pathname doTheDance d = do ..... doDeeDooDa f g d = do ..... doNothing _ = return () main = do mapM_ makeDir (map fst dirLst) mapM_ ((a,b) -> a b) dirLst or even main = do forM_ dirLst $ \(d,f) -> makeDir d >> f d David.

On Sun, Aug 7, 2011 at 07:25, Manfred Lotz
-- initialize empty table P = {}
P.a = "bla1" P.b = "bla2"
and so on.
Now I can refer to each value by name, and I also can easily iterate over the table P.
This looks to me like one of the HList-based record systems. But that could get you into hot water fairly quickly, as while the record/lens packages try to cover up the ugliness, it's all based on some fairly complex type hackery. http://www.haskell.org/haskellwiki/Extensible_record is an overview of the field. -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms
participants (9)
-
Brandon Allbery
-
Daniel Fischer
-
David Place
-
David Virebayre
-
Ertugrul Soeylemez
-
KC
-
Manfred Lotz
-
Michael Snoyman
-
Thiago Negri