Restrict type in phantom data-type

Hello, List! For example, I have specialized (right nameis phantom?) type: data Day a = Day { ... no `a` here } data Sunny data Rainy joyToday :: Day Sunny -> IO () joyToday day = ... melancholyToday :: Day Rainy -> IO () melancholyToday day = ... And I can create (in spite of that it's phantom) some day: let day1 = Day {...} :: Day Sunny joyToday day1 but no problem to create `Day Int`, `Day Char`, etc which is pointless actually (sure "creator"-function can be exported from the module only, but I'm talking about type-level solution). I know that constraints (`... =>`) on data types are redundant/removed from the language. And I'm not sure how it's possible to restrict that parameter `a` (I know that it's possible to Java/C++/Perl6 (not sure), some other languages but how to add such restriction in Haskell? IMHO type families can help but I'm not sure how it will look (Sunny, Rainy are "nullary" type, so...). Is it possible for Haskell too? === Best regards, Paul

This is maybe edging toward haskell-cafe territory, but you can
definitely do this in haskell.
{-# LANGUAGE DataKinds, KindSignatures #-}
data DayType = Sunny | Rainy
data Day (a :: DayType) = Day
sunnyDay :: Day Sunny
sunnyDay = Day
rainyDay :: Day Rainy
rainyDay = Day
-- impossibleDay :: Day ()
-- impossibleDay = Day
On Fri, Sep 1, 2017 at 10:18 AM, Baa
Hello, List!
For example, I have specialized (right nameis phantom?) type:
data Day a = Day { ... no `a` here } data Sunny data Rainy
joyToday :: Day Sunny -> IO () joyToday day = ...
melancholyToday :: Day Rainy -> IO () melancholyToday day = ...
And I can create (in spite of that it's phantom) some day:
let day1 = Day {...} :: Day Sunny joyToday day1
but no problem to create `Day Int`, `Day Char`, etc which is pointless actually (sure "creator"-function can be exported from the module only, but I'm talking about type-level solution).
I know that constraints (`... =>`) on data types are redundant/removed from the language. And I'm not sure how it's possible to restrict that parameter `a` (I know that it's possible to Java/C++/Perl6 (not sure), some other languages but how to add such restriction in Haskell? IMHO type families can help but I'm not sure how it will look (Sunny, Rainy are "nullary" type, so...).
Is it possible for Haskell too?
=== Best regards, Paul _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Fri, Sep 01, 2017 at 05:18:02PM +0300, Baa wrote:
Hello, List!
For example, I have specialized (right nameis phantom?) type:
data Day a = Day { ... no `a` here } data Sunny data Rainy
joyToday :: Day Sunny -> IO () joyToday day = ...
melancholyToday :: Day Rainy -> IO () melancholyToday day = ...
And I can create (in spite of that it's phantom) some day:
let day1 = Day {...} :: Day Sunny joyToday day1
Hello Paul, the usual way is create a module and export `smart` constructors: module MyType (rainy, Day, Sunny) -- *not* Day rainy :: Day Rainy rainy = undefined -- something here That way you can use Day for time signatures but *not* `Day` the constructor. Does this solve your problem?

@Francesco: yes, it's a solution. But more interesting here is to make it on type level, like we do it in D, Java, etc where you can say: "class derived from...", "class before...", "class after...".
On Fri, Sep 01, 2017 at 04:55:32PM +0200, Francesco Ariis wrote:
module MyType (rainy, Day, Sunny) -- *not* Day
I meant to write: -- not `Day(..)` _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (3)
-
Baa
-
David McBride
-
Francesco Ariis