Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  phantom types and record syntax (Dimitri DeFigueiredo)
   2. Re:  phantom types and record syntax (akash g)
   3. Re:  phantom types and record syntax (Brandon Allbery)
   4. Re:  phantom types and record syntax (akash g)
   5. Re:  phantom types and record syntax (akash g)


----------------------------------------------------------------------

Message: 1
Date: Tue, 16 Jun 2015 18:43:38 -0600
From: Dimitri DeFigueiredo <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: [Haskell-beginners] phantom types and record syntax
Message-ID: <[email protected]>
Content-Type: text/plain; charset=windows-1252; format=flowed

Hi All,

I am a little suprised that this program compiles in GHC:

----
data ReqTime = ReqTime
data AckTime = AckTime

data Order a = Order { price  ::Double, volume ::Int, timestamp ::Int }

convertToReq :: Order AckTime -> Order ReqTime
convertToReq o = o{price = 1}

main = putStrLn "Hi!"
----

My trouble is that it seems the record syntax is *implicitly* converting 
from one type to the other. It seems I would have to remove the phantom 
type to avoid this:

----
data Order a = Order { price  ::Double, volume ::Int, timestamp ::Int, 
myType :: a }

convertToReq :: Order AckTime -> Order ReqTime
convertToReq o = o{price = 1}  -- fail!!
----

Could somebody sprinkle some insight into why this is "converted 
automatically" for phantom types? Can I avoid this behavior?

Thanks!

Dimitri


------------------------------

Message: 2
Date: Wed, 17 Jun 2015 09:44:03 +0530
From: akash g <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] phantom types and record syntax
Message-ID:
        <caliga_fp1fmcn7h7cetodlqfj8s73a6zxof+1tnu+dt0auw...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

The phantom type doesn't appear on the actual constructors, only on the
type signatures.  In the function convertToReq, you are changing the
following
1. The type.
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.



That said, I don't see the point of a phantom on a record structure like
this.  Phantoms are more useful when you have multiple data constructors
for a given type and you want to make sure you don't have constructions
that don't make sense.  Like in an interpreter, you don't want to create
expressions that can give rise to an expressions like add a integer to a
string and that sort of thing.

Try this:
http://www.scs.stanford.edu/11au-cs240h/notes/laziness-slides.html

In fact, that set of lecture notes as well as the 2014 class notes are
amazingly good.


On Wed, Jun 17, 2015 at 6:13 AM, Dimitri DeFigueiredo <
[email protected]> wrote:

> Hi All,
>
> I am a little suprised that this program compiles in GHC:
>
> ----
> data ReqTime = ReqTime
> data AckTime = AckTime
>
> data Order a = Order { price  ::Double, volume ::Int, timestamp ::Int }
>
> convertToReq :: Order AckTime -> Order ReqTime
> convertToReq o = o{price = 1}
>
> main = putStrLn "Hi!"
> ----
>
> My trouble is that it seems the record syntax is *implicitly* converting
> from one type to the other. It seems I would have to remove the phantom
> type to avoid this:
>
> ----
> data Order a = Order { price  ::Double, volume ::Int, timestamp ::Int,
> myType :: a }
>
> convertToReq :: Order AckTime -> Order ReqTime
> convertToReq o = o{price = 1}  -- fail!!
> ----
>
> Could somebody sprinkle some insight into why this is "converted
> automatically" for phantom types? Can I avoid this behavior?
>
> Thanks!
>
> Dimitri
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20150617/7a9fb655/attachment-0001.html>

------------------------------

Message: 3
Date: Wed, 17 Jun 2015 00:55:38 -0400
From: Brandon Allbery <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] phantom types and record syntax
Message-ID:
        <CAKFCL4XOrrUfwVmC5xSQQhgmZD=2nPT+q=esbpb+pyzsxw1...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

On Wed, Jun 17, 2015 at 12:14 AM, akash g <[email protected]> wrote:

> The phantom type doesn't appear on the actual constructors, only on the
> type signatures.  In the function convertToReq, you are changing the
> following
> 1. The type.
> 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.
>

I'm not sure I see the difference between the given example and the
"effectively phantom" type in

    foo :: Maybe String -> Maybe Int
    foo x@Nothing = x -- error: Nothing :: Maybe String is not compatible
with Maybe Int
    foo x = ...

-- 
brandon s allbery kf8nh                               sine nomine associates
[email protected]                                  [email protected]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20150617/e2bda278/attachment-0001.html>

------------------------------

Message: 4
Date: Wed, 17 Jun 2015 11:04:51 +0530
From: akash g <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] phantom types and record syntax
Message-ID:
        <CALiga_f_XqDQvVTGH=undekfy-gwcef1mjofv6mm5bqxv05...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

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.
-----------------
data Expr = Num Int             -- atom
          | Str String          -- atom
          | Op BinOp Expr Expr  -- compound
            deriving (Show)

data BinOp = Add | Concat
             deriving (Show)

data Expr1 a = Num1 Int             -- atom
            | Str1 String          -- atom
            | Op1 BinOp (Expr1 a) (Expr1 a)  -- compound
            deriving (Show)

addition :: Expr1 Int -> Expr1 Int -> Expr1 Int
addition (Num1 a) (Num1 b) = Num1 $ a + b

createNum :: Int -> Expr
createNum a = Num a

createStr :: String -> Expr
createStr a = Str a

createNum1 :: Int -> Expr1 Int
createNum1 a = Num1 a


createStr1 :: String -> Expr1 String
createStr1 a = Str1 a


sumExpr :: Expr -> Expr -> Expr
sumExpr a b = Op Add a b

sumExpr1 :: Expr1 Int -> Expr1 Int -> Expr1 Int
sumExpr1 a b = Op1 Add a b

-----------------

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

--------
?> sumExpr (createNum 1) (createStr "a")
Op Add (Num 1) (Str "a")
?> sumExpr1 (createNum1 1) (createStr1 "a")

<interactive>:342:26-39:
    Couldn't match type ?[Char]? with ?Int?
    Expected type: Expr1 Int
      Actual type: Expr1 String
    In the second argument of ?sumExpr1?, namely ?(createStr1 "a")?
    In the expression: sumExpr1 (createNum1 1) (createStr1 "a")
?>
--------

>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.

I think GADTs are much better for things like this for specifying the
constructors, but you'd still have to write sumExpr1 in program.


On Wed, Jun 17, 2015 at 10:25 AM, Brandon Allbery <[email protected]>
wrote:

> On Wed, Jun 17, 2015 at 12:14 AM, akash g <[email protected]> wrote:
>
>> The phantom type doesn't appear on the actual constructors, only on the
>> type signatures.  In the function convertToReq, you are changing the
>> following
>> 1. The type.
>> 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.
>>
>
> I'm not sure I see the difference between the given example and the
> "effectively phantom" type in
>
>     foo :: Maybe String -> Maybe Int
>     foo x@Nothing = x -- error: Nothing :: Maybe String is not compatible
> with Maybe Int
>     foo x = ...
>
> --
> brandon s allbery kf8nh                               sine nomine
> associates
> [email protected]
> [email protected]
> unix, openafs, kerberos, infrastructure, xmonad
> http://sinenomine.net
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20150617/c4dae3c7/attachment-0001.html>

------------------------------

Message: 5
Date: Wed, 17 Jun 2015 11:08:12 +0530
From: akash g <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] phantom types and record syntax
Message-ID:
        <caliga_c4svq2qj0+dvqk8jsorvo+faeaz86tcc_4596qxn6...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Oh, and the above data types were lifted from Stanford's cs240h (the 2011
version).

On Wed, Jun 17, 2015 at 11:04 AM, akash g <[email protected]> wrote:

> 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.
> -----------------
> data Expr = Num Int             -- atom
>           | Str String          -- atom
>           | Op BinOp Expr Expr  -- compound
>             deriving (Show)
>
> data BinOp = Add | Concat
>              deriving (Show)
>
> data Expr1 a = Num1 Int             -- atom
>             | Str1 String          -- atom
>             | Op1 BinOp (Expr1 a) (Expr1 a)  -- compound
>             deriving (Show)
>
> addition :: Expr1 Int -> Expr1 Int -> Expr1 Int
> addition (Num1 a) (Num1 b) = Num1 $ a + b
>
> createNum :: Int -> Expr
> createNum a = Num a
>
> createStr :: String -> Expr
> createStr a = Str a
>
> createNum1 :: Int -> Expr1 Int
> createNum1 a = Num1 a
>
>
> createStr1 :: String -> Expr1 String
> createStr1 a = Str1 a
>
>
> sumExpr :: Expr -> Expr -> Expr
> sumExpr a b = Op Add a b
>
> sumExpr1 :: Expr1 Int -> Expr1 Int -> Expr1 Int
> sumExpr1 a b = Op1 Add a b
>
> -----------------
>
> 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
>
> --------
> ?> sumExpr (createNum 1) (createStr "a")
> Op Add (Num 1) (Str "a")
> ?> sumExpr1 (createNum1 1) (createStr1 "a")
>
> <interactive>:342:26-39:
>     Couldn't match type ?[Char]? with ?Int?
>     Expected type: Expr1 Int
>       Actual type: Expr1 String
>     In the second argument of ?sumExpr1?, namely ?(createStr1 "a")?
>     In the expression: sumExpr1 (createNum1 1) (createStr1 "a")
> ?>
> --------
>
> 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.
>
> I think GADTs are much better for things like this for specifying the
> constructors, but you'd still have to write sumExpr1 in program.
>
>
> On Wed, Jun 17, 2015 at 10:25 AM, Brandon Allbery <[email protected]>
> wrote:
>
>> On Wed, Jun 17, 2015 at 12:14 AM, akash g <[email protected]> wrote:
>>
>>> The phantom type doesn't appear on the actual constructors, only on the
>>> type signatures.  In the function convertToReq, you are changing the
>>> following
>>> 1. The type.
>>> 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.
>>>
>>
>> I'm not sure I see the difference between the given example and the
>> "effectively phantom" type in
>>
>>     foo :: Maybe String -> Maybe Int
>>     foo x@Nothing = x -- error: Nothing :: Maybe String is not
>> compatible with Maybe Int
>>     foo x = ...
>>
>> --
>> brandon s allbery kf8nh                               sine nomine
>> associates
>> [email protected]
>> [email protected]
>> unix, openafs, kerberos, infrastructure, xmonad
>> http://sinenomine.net
>>
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20150617/83fdd5bf/attachment.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 84, Issue 27
*****************************************

Reply via email to