
On Sun, Aug 09, 2015 at 12:16:27AM +0200, MigMit wrote:
1) This might be the code written by someone using your library/framework. In which case it would know about A and B.
Then it's up to me to define and document whatever strictness properties I want for my constructors.
Of course. But it's NOT up to you to restrict the user from using whatever techniques xe wants
Can you explain how any of this "restricts the user from using whatever techniques he wants"?
in existing code. Of course that won't work. But for *new* datatypes choosing one rather than the other gives no difference in terms of denotational semantics.
If it makes the difference for the old code, then it would make the difference for the new code as well.
I fail to see how. Breaking an API makes a difference for old code, but new code is written to the new API.
2) It might be generated by the Template Haskell — which is free to use whatever constructor is fed into it.
OK, so show me what goes wrong!
{-# LANGUAGE TemplateHaskell #-} module TH where import Language.Haskell.TH check :: Name -> ExpQ check c = [|let x = case x of $(conP c [[p|_|]]) -> $(conE c) 1 in x|]
Right, you can distinguish data declarations from newtype declarations this way, but by using Template Haskell you can also distinguish * data A = A Int * data A = A { a :: Int } * data A = A' Int * data A = A Int !(), and * newtype B = B A (where A has one of the above definitions) from each other. My claim is that * data B = B !A is as indistinguishable from the above four as they are from each other. Tom