<div dir="ltr"><div><div><div><div>When you have phantom types, you get can catch logically illegal functions in the type itself.  You can create constructors for types so that you can't create illegal expressions.<br>-----------------<br>data Expr = Num Int             -- atom<br>          | Str String          -- atom<br>          | Op BinOp Expr Expr  -- compound<br>            deriving (Show)<br><br>data BinOp = Add | Concat<br>             deriving (Show)<br><br>data Expr1 a = Num1 Int             -- atom<br>            | Str1 String          -- atom<br>            | Op1 BinOp (Expr1 a) (Expr1 a)  -- compound<br>            deriving (Show)<br><br>addition :: Expr1 Int -> Expr1 Int -> Expr1 Int<br>addition (Num1 a) (Num1 b) = Num1 $ a + b<br><br>createNum :: Int -> Expr<br>createNum a = Num a<br><br>createStr :: String -> Expr <br>createStr a = Str a<br><br>createNum1 :: Int -> Expr1 Int<br>createNum1 a = Num1 a<br><br><br>createStr1 :: String -> Expr1 String<br>createStr1 a = Str1 a<br><br><br>sumExpr :: Expr -> Expr -> Expr<br>sumExpr a b = Op Add a b<br><br>sumExpr1 :: Expr1 Int -> Expr1 Int -> Expr1 Int<br>sumExpr1 a b = Op1 Add a b<br><br>-----------------<br><br></div>With the above, you can create expressions that make no sense in real life (like adding/concating a number to a string ).  When I execute this in GHCI, I get the following <br><br>--------<br>λ> sumExpr (createNum 1) (createStr "a")<br>Op Add (Num 1) (Str "a")<br>λ> sumExpr1 (createNum1 1) (createStr1 "a")<br><br><interactive>:342:26-39:<br>    Couldn't match type ‘[Char]’ with ‘Int’<br>    Expected type: Expr1 Int<br>      Actual type: Expr1 String<br>    In the second argument of ‘sumExpr1’, namely ‘(createStr1 "a")’<br>    In the expression: sumExpr1 (createNum1 1) (createStr1 "a")<br>λ> <br>--------<br><br></div><div>From the above, it is clear that as long as we write constructors taking into account the types (called smart-constructors), we can prevent expressions from being created.  I do admit that this makes it a bit tedious as we would have to write the constructors by hand, but we get type level guarantees.<br><br></div><div>I think GADTs are much better for things like this for specifying the constructors, but you'd still have to write sumExpr1 in program.<br></div></div></div><div><div><div><br></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 17, 2015 at 10:25 AM, Brandon Allbery <span dir="ltr"><<a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span class=""><div class="gmail_quote">On Wed, Jun 17, 2015 at 12:14 AM, akash g <span dir="ltr"><<a href="mailto:akaberto@gmail.com" target="_blank">akaberto@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>The phantom type doesn't appear on the actual constructors, only on the  type signatures.  In the function convertToReq, you are changing the following<br></div>1. The type.<br></div>2. The value of the price record (actually returning a new value with the price record changed to one and the rest of the fields being the same.<br></blockquote></div><br></span>I'm not sure I see the difference between the given example and the "effectively phantom" type in</div><div class="gmail_extra"><br></div><div class="gmail_extra">    foo :: Maybe String -> Maybe Int</div><div class="gmail_extra">    foo x@Nothing = x -- error: Nothing :: Maybe String is not compatible with Maybe Int</div><div class="gmail_extra">    foo x = ...<span class="HOEnZb"><font color="#888888"><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div>brandon s allbery kf8nh                               sine nomine associates</div><div><a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>                                  <a href="mailto:ballbery@sinenomine.net" target="_blank">ballbery@sinenomine.net</a></div><div>unix, openafs, kerberos, infrastructure, xmonad        <a href="http://sinenomine.net" target="_blank">http://sinenomine.net</a></div></div></div>
</font></span></div></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>