I'm using a modified version of the Document-View model for application design. The commands in the language are defined in the Cell data type:
https://github.com/timthelion/gridhaskell-haskarrow/blob/master/Cell.lhs
Some Cell types, like Jump, have a long crooked line comming out of them called a Path. This line is held in the path :: Maybe Path feild.
When I'm drawing the Cell tree, I have a function that extracts these Paths. https://github.com/timthelion/gridhaskell-haskarrow/blob/master/ArrowDrawing.lhs#L75
It used to be, that more types of Cell than just the Jump Cell had a path.
As I removed these Paths from the Cell datatype, my line drawing function started crashing, whenever it encountered those Cell types. By having chosen to use the short hand record selector syntax rather than the long hand place value syntax, I caused a runtime error in my code.
I could of course have written the same function like this:
> where path_points => case> case cell ofTypes of cells which have paths:> Cell.Jump _ path -> Just path> _ -> Nothing of> Just path -> maybe [] (\p -> [Path.point p]) (Cell.path cell)> Nothing -> []
Record selection is a more convenient syntax. It *could* be usefull for making more maintainable code(the reason why I choose it). The method I have chosen *would* be more maintainable in the case I want to add another feild to Jump. In that case I would not have to re-write the path_points function. Sadly, due to GHC's unnessesary and complete inability to do type safety checking, what should have been a convenient tool, has become an unnessecary source of runtime errors!
---------- Původní zpráva ----------
Od: John Meacham <john@repetae.net>
Datum: 27. 5. 2012
Předmět: Re: [Haskell-cafe] Record syntax, reopening a can of worms.
Is it any more ridiculous than
> f x@Nothing {} = fromJust x
> main = print (f Nothing)
crashing at run time? That is what you are expressing with your first
one. This issue is completely unrelated to the named field syntax,
they behave exactly like data types with non-named fields.
However, you can achieve something like what you want with phantom types.
> data ALike
> data BLike
>data MyData t = A {a::Int,
> b::Int} |
> B {c::Int}
> mkA x y = A x y :: MyData ALike
> mkB x = B x :: MyData BLike
then you can write functions of
'MyData ALike' to indicate it will only have 'A' as a constructor
'MyData BLike' to indicate it will only have 'B'
and 'forall t . MyData t' for functions that can take a general MyData
that can have either.
John