How to nest arbitrary things

Hello all, I was trying to model things which can contain other things. This is easy as long as containers and the contained items all can be described in the same fashion. However when I want to model - say - trucks containing boxes containing parcels containing cans and trucks, boxes, parcels and cans are not of the same type, then this nested thing will become a type in its own right and it will be of a different type than trucks containing cans (which are not wrappen in parcels ...) As long as I can squeeze trucks, boxes ... into one type, possibly by using a "container_type" attribute, there is no problem. Is this the only way to do this? Is there an idiom?

martin writes:
Hello all,
I was trying to model things which can contain other things. This is easy as long as containers and the contained items all can be described in the same fashion. However when I want to model - say -
trucks containing boxes containing parcels containing cans
and trucks, boxes, parcels and cans are not of the same type, then this nested thing will become a type in its own right and it will be of a different type than trucks containing cans (which are not wrappen in parcels ...)
As long as I can squeeze trucks, boxes ... into one type, possibly by using a "container_type" attribute, there is no problem. Is this the only way to do this? Is there an idiom?
Well, you can always make Truck a bit generic: data Truck a = Truck [a] Then you have have a truck of boxes (`Truck Box`) or a truck of cans (`Truck Can`). But maybe that's not really your question? /M -- Magnus Therning OpenPGP: 0x927912051716CE39 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus Any sufficiently advanced technology is indistinguishable from a rigged demo. -- Andy Finkel

On 2015-12-21 14:51, Imants Cekusins wrote:
trucks containing boxes containing parcels containing cans
.. or try this type:
data Item a = Truck a [Item] | Box a [Item] | Parcel a [Item] | Can a [Item]
I guess you'd need that type if you want to be able to express http://i.telegraph.co.uk/multimedia/archive/01845/truck-on-truck-on-_1845173... -- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing

http://i.telegraph.co.uk/multimedia/archive/01845/truck-on-truck-on-_1845173...
:D
Garbage In Garbage Out.
well Martin would like to
model things which can contain other things.

On Mon, Dec 21, 2015 at 8:51 PM, Imants Cekusins

Personally I'd try to use the type system, if possible.
data Box a = Box [a]
data Parcel a = Parcel [a]
data Can = Can
data Truck a = Truck {
tname :: String,
truckContents :: [a]
}
oneboxoftwocanstruck :: Truck (Box Can)
oneboxoftwocanstruck = Truck "Truck of Boxes of Cans" [Box [Can,Can]]
onecantruck :: Truck Can
onecantruck = Truck "Truck of Cans" [Can]
This gets some of the type safety without bogging you down too much. You
can still end up with parcels with trucks in them, but it's not too bad.
At least cans are just cans, and functions can be written for trucks that
only work on trucks, for example.
On Mon, Dec 21, 2015 at 4:40 AM, martin
Hello all,
I was trying to model things which can contain other things. This is easy as long as containers and the contained items all can be described in the same fashion. However when I want to model - say -
trucks containing boxes containing parcels containing cans
and trucks, boxes, parcels and cans are not of the same type, then this nested thing will become a type in its own right and it will be of a different type than trucks containing cans (which are not wrappen in parcels ...)
As long as I can squeeze trucks, boxes ... into one type, possibly by using a "container_type" attribute, there is no problem. Is this the only way to do this? Is there an idiom?
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On 2015-12-21 10:40, martin wrote:
I was trying to model things which can contain other things. This is easy as long as containers and the contained items all can be described in the same fashion. However when I want to model - say -
trucks containing boxes containing parcels containing cans
and trucks, boxes, parcels and cans are not of the same type, then this nested thing will become a type in its own right and it will be of a different type than trucks containing cans (which are not wrappen in parcels ...)
As long as I can squeeze trucks, boxes ... into one type, possibly by using a "container_type" attribute, there is no problem. Is this the only way to do this? Is there an idiom?
In addition to what the others wrote (I'd personally probably start with the 'data Truck a = Truck [a]' idea) you could also use the type system to express the possible *legal* ways to nest the load of a truck, e.g.: -- A Can can't contain anything data Can = Can -- A Parcel consists of zero or more cans data Parcel = Parcel [Can] -- A Box can be empty or contain a mixture of cans and parcels data BoxContent = BCCan Can | BCParcel Parcel data Box = Box [BoxContent] -- A Truck can be empty or contain a mixture of cans, parcels and boxes data TruckConent = TCCan Can | TCParcel Parcel | TCBox Box data Truck = Truck [TruckContent] This might be too annoying to deal with though, i.e. the gain of type safety is not big enough to actually follow this path. -- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing

Am 12/21/2015 um 03:21 PM schrieb Frerich Raabe:
On 2015-12-21 10:40, martin wrote:
I was trying to model things which can contain other things. This is easy as long as containers and the contained items all can be described in the same fashion. However when I want to model - say -
trucks containing boxes containing parcels containing cans
and trucks, boxes, parcels and cans are not of the same type, then this nested thing will become a type in its own right and it will be of a different type than trucks containing cans (which are not wrappen in parcels ...)
As long as I can squeeze trucks, boxes ... into one type, possibly by using a "container_type" attribute, there is no problem. Is this the only way to do this? Is there an idiom?
In addition to what the others wrote (I'd personally probably start with the 'data Truck a = Truck [a]' idea) you could also use the type system to express the possible *legal* ways to nest the load of a truck, e.g.:
-- A Can can't contain anything data Can = Can
-- A Parcel consists of zero or more cans data Parcel = Parcel [Can]
-- A Box can be empty or contain a mixture of cans and parcels data BoxContent = BCCan Can | BCParcel Parcel data Box = Box [BoxContent]
-- A Truck can be empty or contain a mixture of cans, parcels and boxes data TruckConent = TCCan Can | TCParcel Parcel | TCBox Box data Truck = Truck [TruckContent]
This might be too annoying to deal with though, i.e. the gain of type safety is not big enough to actually follow this path.
That's fine. I'm happy not to be able to pack a truck into another truck. Only problem is that I don't know how to write an "unpack" function, which removes one level of nesting. I can only write unpackTruck, unpackParcel ... I suppose the ability to write a generic unpack function implies that there can be a generic pack function and then I could pack a truck into another truck.

On Mon, Dec 21, 2015 at 06:00:06PM +0100, martin wrote:
That's fine. I'm happy not to be able to pack a truck into another truck. Only problem is that I don't know how to write an "unpack" function, which removes one level of nesting. I can only write unpackTruck, unpackParcel ...
I suppose the ability to write a generic unpack function implies that there can be a generic pack function and then I could pack a truck into another truck.
I would say typeclasses might help you, but before that, what would the unpack function signature look like? unpack :: (Package s) => s a -> [a] Like this? If so, I don't see much benefit (or what problem we're trying to solve) in trucks>boxes>parcels>cans types.

Am 12/21/2015 um 06:30 PM schrieb Francesco Ariis:
On Mon, Dec 21, 2015 at 06:00:06PM +0100, martin wrote:
That's fine. I'm happy not to be able to pack a truck into another truck. Only problem is that I don't know how to write an "unpack" function, which removes one level of nesting. I can only write unpackTruck, unpackParcel ...
I suppose the ability to write a generic unpack function implies that there can be a generic pack function and then I could pack a truck into another truck.
I would say typeclasses might help you, but before that, what would the unpack function signature look like?
unpack :: (Package s) => s a -> [a]
Like this? If so, I don't see much benefit (or what problem we're trying to solve) in trucks>boxes>parcels>cans types.
Unpacking should separate the container from its contents, i.e. given a packed container it should return an empty container and whatever was inside.

On Mon, Dec 21, 2015 at 08:41:47PM +0100, martin wrote:
I would say typeclasses might help you, but before that, what would the unpack function signature look like?
unpack :: (Package s) => s a -> [a]
Like this? If so, I don't see much benefit (or what problem we're trying to solve) in trucks>boxes>parcels>cans types.
Unpacking should separate the container from its contents, i.e. given a packed container it should return an empty container and whatever was inside.
I'd still ask for a type signature if you feel it's possible, it clears things up (and/or highlights where the type system is getting in the way). An I'd still argue that "arbitrarily nestable" things is a bad idea, as Kim-Ee Yeoh explained. I like Haskell type system because carefully designed types "lead the way": some 'wrong' code won't even compile. In real life, what are we trying to model? Why is `unpack` useful/needed? How would I use its output? (a valid answer being: "just a mental experiment")
participants (7)
-
David McBride
-
Francesco Ariis
-
Frerich Raabe
-
Imants Cekusins
-
Kim-Ee Yeoh
-
Magnus Therning
-
martin