[GHC] #12363: Type application for infix
GHC
ghc-devs at haskell.org
Tue Jan 10 13:17:51 UTC 2017
#12363: Type application for infix
-------------------------------------+-------------------------------------
Reporter: Iceland_jack | Owner:
Type: feature request | Status: new
Priority: lowest | Milestone:
Component: Compiler | Version: 8.0.1
(Parser) | Keywords:
Resolution: | TypeApplications
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by Iceland_jack):
Replying to [comment:15 rwbarton]:
> I don't know if it's the sheer number of updates to this ticket, but
this syntax is starting to look fairly natural to me.
Just According to Keikaku.⁽¹⁾
⁽¹⁾
[https://www.reddit.com/r/OutOfTheLoop/comments/467byi/what_the_hell_is_keikaku/
(Translator's note: keikaku means plan)]
> Most of these examples don't look like code I would ever write, but the
{{{`catch` @IOException}}} example is pretty sweet.
It works especially well with operators where the specified type does not
appear in the return type: having to privilege one side over the other
feels asymmetric, the [https://hackage.haskell.org/package/intervals
intervals] package documentation gives a lot of good examples where this
is useful:
{{{#!hs
-- >>> (5 ... 10 :: Interval Double) <! (20 ... 30 :: Interval Double)
-- True
>>> (5 ... 0) <! @Double (20 ... 30)
True
-- >>> (20 ... 40 :: Interval Double) `contains` (15 ... 35 :: Interval
Double)
-- False
>>> (20 ... 40) `contains` @Double (15 ... 35)
False
}}}
but also simpler examples, I will avoid writing an explicit annotation if
I can
{{{#!hs
-- >>> (0.1 :: Float) + 0.2 == 0.3
-- True
>>> 0.1 + 0.2 == @Float 0.3
True
-- >>> 0.1 + 0.2 == (0.3 :: Double)
-- False
>>> 0.1 + 0.2 == @Double 0.3
False
-- >>> 0 `elem` [1,2::Int,3]
-- False
>>> 0 `elem` @[] @Int [1,2,3]
False
}}}
For most examples you can easily annotate some other part of the
expression to get the same effect. My experience is that infix type
application leads to less thinking, more consistency (in where the type
goes) and more resistance to change: I prefer the uncommented versions
{{{#!hs
-- n `hashWithSalt` (fromIntegral (ptrToIntPtr s) :: Int)
-- n `hashWithSalt` fromIntegral @_ @Int (ptrToIntPtr s)
n `hashWithSalt` @Int fromIntegral (ptrToIntPtr s)
}}}
{{{#!hs
-- Var a -> digest c (1 :: Word8) `digest` a
-- App f x -> digest c (2 :: Word8) `digest` f `digest` x
-- HardType h -> digest c (3 :: Word8) `digest` h
-- Forall k tvs cs b -> digest c (4 :: Word8) `digest` k `digest` tvs
`digest` cs `digest` b
-- Loc _ ty -> digest c ty
-- Exists k tvs cs -> digest c (5 :: Word8) `digest` k `digest` tvs
`digest` cs
-- And xs -> digest c (6 :: Word8) `digest` xs
Var a -> c `digest` @Word8 1 `digest` a
App f x -> c `digest` @Word8 2 `digest` f `digest` x
HardType h -> c `digest` @Word8 3 `digest` h
Forall k tvs cs b -> c `digest` @Word8 4 `digest` k `digest` tvs `digest`
cs `digest` b
Loc _ ty -> c `digest` ty
Exists k tvs cs -> c `digest` @Word8 5 `digest` k `digest` tvs `digest`
cs
And xs -> c `digest` @Word8 6 `digest` xs
}}}
and
{{{#!hs
-- tAG_BITS_MAX = (1 `shiftL` tAG_BITS) :: Int
tAG_BITS_MAX = 1 `shiftL` @Int tAG_BITS
}}}
----
I would still say the main usefulness is pedagogy: I will not introduce
invalid syntax when explaining things to newcomers, but for questions like
[https://www.reddit.com/r/haskellquestions/comments/5mtk8v/instance_eq_question/
this]
{{{#!hs
Nodo x ys zs == Nodo x' ys' zs' = x == x' && ys == ys' && zs == zs'
}}}
maybe it would help to write it like this, to show the different
instantiations of `==`
{{{#!hs
Nodo x ys zs == Nodo x' ys' zs' =
x == @a x'
&& ys == @(Heap a) ys'
&& zs == @(Heap a) zs'
}}}
In the end it's up to what the community thinks
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12363#comment:16>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list