[Haskell-cafe] Language extension proposal: aspects

Dmitry Olshansky olshanskydr at gmail.com
Sun May 7 09:21:06 UTC 2017


If we have
allEven :: (Monoid Bool, Integral a) => [a] -> Bool
then, as usual, we have to define an aspect for Bool on the caller's side.

So there are two possibilities for user:
- fix an aspect in the function, there is no need for aspect on caller side
(What will be if on the caller side we already have an another aspect?!
Probably we can ignore it...)
- aspect-oriented constraint in the function's signature and fix an aspect
for the caller

I think that the second case is more useful. We prefer to write generalized
functions!

But in this case I'm afraid that we end-up with the same noise as for the
newtype. But instead of construct to and deconstruct from newtype we will
have to define aspects on type level for caller and define constraint for
function. Usually type-level syntax is more complicated...


2017-05-06 23:55 GMT+03:00 MarLinn <monkleyon at gmail.com>:

> On 2017-05-06 21:37, Dmitry Olshansky wrote:
>
>> How does compiler can infer a type for "allEven = foldMap even" ?
>>
>> Something like
>> allEven :: (Monoid (aspect Bool), Integral a) => [a] -> Bool ?
>>
>
> I hadn't thought about inference actually. But even if the compiler
> inferred a type, it would still fail with a missing constraint. So I don't
> strongly care what the implied constraint is, as long as the error message
> is comprehensible. Maybe it could mention aspects in the future, but that's
> not even necessary. So basically the inferred type would just be
>
>         allEven :: (Monoid Bool, Integral a) => [a] -> Bool
>
> The compiler would just know "I need a Monoid instance for Bool!" as it
> does right now. And just as now, it knows where to look – the only
> difference is that with my proposal that place to look has a different name.
>
> Should all Bool's in function body have the same aspects?
>>
>
> Yes, if the aspect comes from a type signature. If the type signature is
> local, it would be local to its region of application. For example:
>
> ---
> module Test where
>
>     import qualified Data.Bool under (Default, Data.Aspect.Bool.All) as
> A_All_ (Bool)
>     import qualified Data.Bool under (Default, Data.Aspect.Bool.Any) as
> A_Any_ (Bool)
>
>     test2 :: (Integral a) => [a] -> Bool
>     test2 xs = (foldMap even xs :: A_All_.Bool) == not (foldMap odd xs ::
> A_Any_.Bool)
>
> The type is imported twice with different names and under different
> aspects. The local type signatures use these names to define which are the
> right instances.
>
> An alternative would be something like
>
>     test2 :: (Integral a) => [a] -> Bool
>     test2 xs = (foldMap even xs :: (Bool under A_All_)) == not (foldMap
> odd xs :: (Bool under A_Any_))
>
> which would make the aspect-nature clearer. But I didn't want to introduce
> even more syntax, especially as the naming scheme is already enough.
>
> Was that clarifying?
>
> I have to say, your questions did make me ponder how much of my proposal
> would already be possible by exploiting type families. I'm not sure yet,
> but I'll think about it. So thanks!
>
>
> Cheers,
> MarLinn
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170507/349b2a8f/attachment.html>


More information about the Haskell-Cafe mailing list