mutually recursive types

Hi, I am learning the haskell programming language and had tried to define the following types: type Scenario = (String, String, [Step]) type Step = (String, Scenario, String, String, String) Notice that Scenario depends on a list of steps and Step has a dependence with scenario. I know that this is a kind of "bad smell".... in Haskell, are there any pattern or language idiom to deal with cyclical dependences? Regards, Rodrigo.

"rodrigo.bonifacio"
Hi, I am learning the haskell programming language and had tried to define the following types:
type Scenario = (String, String, [Step]) type Step = (String, Scenario, String, String, String)
data Scenario = Scenario String String [Step] data Step = Step String Scenario String String String -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Rodrigo wrote:
type Scenario = (String, String, [Step]) type Step = (String, Scenario, String, String, String)
Recursive types are not supported by type-declarations. use data declarations instead: data Scenario = Scenario String String [Step] data Step = Step String Scenario String String String As a general rule, data declaration are more approbiate then type declarations with a tuple on the right-hand-side. a type declarations introduces a type synonym, that is, a new name for an existing type. Data declarations introduce a new type. most of the time, you want new types, not more names for the same types. different names for the same thing lead to confusion, but different things for different usages lead to static type safety. (But this is only a general rule, and sometimes you want exactly the behaviour of type synonyms, of course) Tillmann

Notice that Scenario depends on a list of steps and Step has a dependence with scenario. I know that this is a kind of "bad smell".... in Haskell, are there any pattern or language idiom to deal with cyclical dependences?
Just a little something to add, this is not a "bad smell" at all... in fact, recursive (including mutually recursive) data types are the bread and butter of Haskell (and functional languages in general). For example: data BinTree a = Empty | Branch a (BinTree a) (BinTree a) This says that a binary tree containing 'a's is either Empty, or a Branch consisting of an 'a' and two binary trees. This isn't stinky, it's quite elegant. Your Scenario and Step data types look just peachy from an idiomatic point of view; the solution (as others have pointed out) is to use data declarations rather than type synonyms. -Brent
participants (4)
-
Brent Yorgey
-
Jon Fairbairn
-
rodrigo.bonifacio
-
Tillmann Rendel