MultiCase alternative

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
27 messages Options
12
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

MultiCase alternative

Baa
Hello, Everyone!

As I understand "MultiCase" proposal was not approved, so my question
is: is there alternatives to multi-case? I have code like:

  case x of
    A a -> ..
    B b -> ..
    C c -> --same--
    D c -> --same--

and I want to merge code of "C c" with "D c" branch. Anywhere, in
general: is any alternatives to make "OR"s in patterns? I don't see how
to do it with pattern guards, pattern synonyms, views extensions and
don't see another related extensions.

Something like "(C|D) c -> ..."


===
Best regards, Paul
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Malcolm Wallace-2
case x of
  A a -> ..
  B b -> ..
  C c -> f c
  D d -> f d
    where f cd = ...


On 15 Jun 2017, at 15:11, Baa wrote:

> Hello, Everyone!
>
> As I understand "MultiCase" proposal was not approved, so my question
> is: is there alternatives to multi-case? I have code like:
>
>  case x of
>    A a -> ..
>    B b -> ..
>    C c -> --same--
>    D c -> --same--
>
> and I want to merge code of "C c" with "D c" branch. Anywhere, in
> general: is any alternatives to make "OR"s in patterns? I don't see how
> to do it with pattern guards, pattern synonyms, views extensions and
> don't see another related extensions.
>
> Something like "(C|D) c -> ..."
>
>
> ===
> Best regards, Paul
> _______________________________________________
> 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.

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Bardur Arantsson-2
In reply to this post by Baa
On 2017-06-15 16:11, Baa wrote:

> Hello, Everyone!
>
> As I understand "MultiCase" proposal was not approved, so my question
> is: is there alternatives to multi-case? I have code like:
>
>   case x of
>     A a -> ..
>     B b -> ..
>     C c -> --same--
>     D c -> --same--
>
> and I want to merge code of "C c" with "D c" branch. Anywhere, in
> general: is any alternatives to make "OR"s in patterns? I don't see how
> to do it with pattern guards, pattern synonyms, views extensions and
> don't see another related extensions.
>

Create a function.

Regards,

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Bram Neijt
In reply to this post by Baa

Hi Paul,

I'm nit experienced in Haskell, so I don't have a solution. But the following keywords spring to mind:
Ignore the syntactic sugar and see if any of the alternative syntaxes are more flexible
https://wiki.haskell.org/Case

Create a DSL.

Greetings,

Bram


On Thu, 15 Jun 2017, 16:13 Baa, <[hidden email]> wrote:
Hello, Everyone!

As I understand "MultiCase" proposal was not approved, so my question
is: is there alternatives to multi-case? I have code like:

  case x of
    A a -> ..
    B b -> ..
    C c -> --same--
    D c -> --same--

and I want to merge code of "C c" with "D c" branch. Anywhere, in
general: is any alternatives to make "OR"s in patterns? I don't see how
to do it with pattern guards, pattern synonyms, views extensions and
don't see another related extensions.

Something like "(C|D) c -> ..."


===
Best regards, Paul
_______________________________________________
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.

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Li-yao Xia-2
In reply to this post by Baa
Hi Paul,

This looks like the or-patterns proposal:

https://github.com/ghc-proposals/ghc-proposals/pull/43

I'm not sure what you call MultiCase though. Is the above what you were
refering to?

Here are some alternatives with current Haskell, the first one is to be
preferred:

- Factor out the alternatives in a function.

       ...
         case x of
           ...
           C c -> f c
           D c -> f c
       where
         f c = ...

- If your C and D constructors have similar enough meanings, you might
want to fuse them into a single constructor with a separate tag:

       data T = A TA | B TB | CD CorD TC
       data CorD = C | D

   so that you can write

       case x of
         ...
         CD _ c -> ...

- With pattern synonyms + view patterns, although it takes some effort
to set up and confuses the exhaustiveness checker.

       matchCorD :: T -> Maybe C
       matchCorD (C c) = Just c
       matchCorD (D c) = Just c
       matchCorD _ = Nothing

       pattern CD :: C -> T
       pattern CD c <- (matchCorD -> Just c)

   you can now write

       case x of
         ...
         CD c -> ...

Li-yao


On 06/15/2017 10:11 AM, Baa wrote:

> Hello, Everyone!
>
> As I understand "MultiCase" proposal was not approved, so my question
> is: is there alternatives to multi-case? I have code like:
>
>    case x of
>      A a -> ..
>      B b -> ..
>      C c -> --same--
>      D c -> --same--
>
> and I want to merge code of "C c" with "D c" branch. Anywhere, in
> general: is any alternatives to make "OR"s in patterns? I don't see how
> to do it with pattern guards, pattern synonyms, views extensions and
> don't see another related extensions.
>
> Something like "(C|D) c -> ..."
>
>
> ===
> Best regards, Paul
> _______________________________________________
> 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.

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Sylvain Henry-2
In reply to this post by Baa
Hi,

You can combine ViewPatterns and PatternSynonyms to  obtain this desired
effect:

{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE PatternSynonyms #-}

data X a b c
    = A a
    | B b
    | C c
    | D c
    deriving (Show)


cOrD :: X a b c -> Maybe c
cOrD (A _) = Nothing
cOrD (B _) = Nothing
cOrD (C c) = Just c
cOrD (D c) = Just c

pattern CorD :: c -> X a b c
pattern CorD c <- (cOrD -> Just c)

main :: IO ()
main = do
    let
       -- x = A "An a" :: X String String String
       -- x = B "A b" :: X String String String
       x = C "A c" :: X String String String
       --x = D "A d" :: X String String String

    case x of
       A a    -> putStrLn ("A:" ++ show a)
       B b    -> putStrLn ("B:" ++ show b)
       CorD c -> putStrLn ("CorD:" ++ show c)


Note that you lose completeness checking:

Test.hs:30:4: warning: [-Wincomplete-patterns]
     Pattern match(es) are non-exhaustive
     In a case alternative:
         Patterns not matched:
             (C _)
             (D _)

Cheers,
Sylvain


On 15/06/2017 16:11, Baa wrote:

> Hello, Everyone!
>
> As I understand "MultiCase" proposal was not approved, so my question
> is: is there alternatives to multi-case? I have code like:
>
>    case x of
>      A a -> ..
>      B b -> ..
>      C c -> --same--
>      D c -> --same--
>
> and I want to merge code of "C c" with "D c" branch. Anywhere, in
> general: is any alternatives to make "OR"s in patterns? I don't see how
> to do it with pattern guards, pattern synonyms, views extensions and
> don't see another related extensions.
>
> Something like "(C|D) c -> ..."
>
>
> ===
> Best regards, Paul
> _______________________________________________
> 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.

_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
In reply to this post by Bardur Arantsson-2
Hmm, seems there is a way:

  {-# LANGUAGE ViewPatterns              #-}

  isCD (C c) = c
  isCD (D c) = c

  case x of
    A a -> ..
    B b -> ..
    (isCD -> x) -> ..process-x..


> On 2017-06-15 16:11, Baa wrote:
> > Hello, Everyone!
> >
> > As I understand "MultiCase" proposal was not approved, so my
> > question is: is there alternatives to multi-case? I have code like:
> >
> >   case x of
> >     A a -> ..
> >     B b -> ..
> >     C c -> --same--
> >     D c -> --same--
> >
> > and I want to merge code of "C c" with "D c" branch. Anywhere, in
> > general: is any alternatives to make "OR"s in patterns? I don't see
> > how to do it with pattern guards, pattern synonyms, views
> > extensions and don't see another related extensions.
> >  
>
> Create a function.
>
> Regards,
>
> _______________________________________________
> 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.
_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
In reply to this post by Li-yao Xia-2
Hello, Li-yao! I mean this: https://wiki.haskell.org/MultiCase


> Hi Paul,
>
> This looks like the or-patterns proposal:
>
> https://github.com/ghc-proposals/ghc-proposals/pull/43
>
> I'm not sure what you call MultiCase though. Is the above what you
> were refering to?
>
> Here are some alternatives with current Haskell, the first one is to
> be preferred:
>
> - Factor out the alternatives in a function.
>
>        ...
>          case x of
>            ...
>            C c -> f c
>            D c -> f c
>        where
>          f c = ...
>
> - If your C and D constructors have similar enough meanings, you
> might want to fuse them into a single constructor with a separate tag:
>
>        data T = A TA | B TB | CD CorD TC
>        data CorD = C | D
>
>    so that you can write
>
>        case x of
>          ...
>          CD _ c -> ...
>
> - With pattern synonyms + view patterns, although it takes some
> effort to set up and confuses the exhaustiveness checker.
>
>        matchCorD :: T -> Maybe C
>        matchCorD (C c) = Just c
>        matchCorD (D c) = Just c
>        matchCorD _ = Nothing
>
>        pattern CD :: C -> T
>        pattern CD c <- (matchCorD -> Just c)
>
>    you can now write
>
>        case x of
>          ...
>          CD c -> ...
>
> Li-yao
>
>
> On 06/15/2017 10:11 AM, Baa wrote:
> > Hello, Everyone!
> >
> > As I understand "MultiCase" proposal was not approved, so my
> > question is: is there alternatives to multi-case? I have code like:
> >
> >    case x of
> >      A a -> ..
> >      B b -> ..
> >      C c -> --same--
> >      D c -> --same--
> >
> > and I want to merge code of "C c" with "D c" branch. Anywhere, in
> > general: is any alternatives to make "OR"s in patterns? I don't see
> > how to do it with pattern guards, pattern synonyms, views
> > extensions and don't see another related extensions.
> >
> > Something like "(C|D) c -> ..."
> >
> >
> > ===
> > Best regards, Paul
> > _______________________________________________
> > 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.  
>

_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
In reply to this post by Sylvain Henry-2
Hmm, Sylvain, this is more interesting than my variant. Thank you a lot!

> Hi,
>
> You can combine ViewPatterns and PatternSynonyms to  obtain this
> desired effect:
>
> {-# LANGUAGE ViewPatterns #-}
> {-# LANGUAGE PatternSynonyms #-}
>
> data X a b c
>     = A a
>     | B b
>     | C c
>     | D c
>     deriving (Show)
>
>
> cOrD :: X a b c -> Maybe c
> cOrD (A _) = Nothing
> cOrD (B _) = Nothing
> cOrD (C c) = Just c
> cOrD (D c) = Just c
>
> pattern CorD :: c -> X a b c
> pattern CorD c <- (cOrD -> Just c)
>
> main :: IO ()
> main = do
>     let
>        -- x = A "An a" :: X String String String
>        -- x = B "A b" :: X String String String
>        x = C "A c" :: X String String String
>        --x = D "A d" :: X String String String
>
>     case x of
>        A a    -> putStrLn ("A:" ++ show a)
>        B b    -> putStrLn ("B:" ++ show b)
>        CorD c -> putStrLn ("CorD:" ++ show c)
>
>
> Note that you lose completeness checking:
>
> Test.hs:30:4: warning: [-Wincomplete-patterns]
>      Pattern match(es) are non-exhaustive
>      In a case alternative:
>          Patterns not matched:
>              (C _)
>              (D _)
>
> Cheers,
> Sylvain
>
>
> On 15/06/2017 16:11, Baa wrote:
> > Hello, Everyone!
> >
> > As I understand "MultiCase" proposal was not approved, so my
> > question is: is there alternatives to multi-case? I have code like:
> >
> >    case x of
> >      A a -> ..
> >      B b -> ..
> >      C c -> --same--
> >      D c -> --same--
> >
> > and I want to merge code of "C c" with "D c" branch. Anywhere, in
> > general: is any alternatives to make "OR"s in patterns? I don't see
> > how to do it with pattern guards, pattern synonyms, views
> > extensions and don't see another related extensions.
> >
> > Something like "(C|D) c -> ..."
> >
> >
> > ===
> > Best regards, Paul
> > _______________________________________________
> > 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.  
>
> _______________________________________________
> 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.
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

MarLinn
In reply to this post by Baa

> Hello, Li-yao! I mean this: https://wiki.haskell.org/MultiCase
>
>> Hi Paul,
>>
>> This looks like the or-patterns proposal:
>>
>> https://github.com/ghc-proposals/ghc-proposals/pull/43
>>
>>

You can see on github that it's just "dormant". But the examples in this
thread made me have an interesting, even more general idea: we have
functions on term-level and type-level – why not on pattern-level?

Here's a very rough draft of what I imagine:

        {-# LANGUAGE PatternFamilies, PatternKinds #-}
       
       
        data Dt a = A a | B a | C a | D a deriving ( Show )

        pattern (∥) ∷ (Pattern a → T) → (Pattern a → T) → (T → U) → (a → U)
        pattern (a ∥ _) f = f a
        pattern (_ ∥ b) f = f b

        infixl 2 pattern ∥
 
        foo ∷ (Show a) ⇒ Dt a → String
        foo (A a) = …
        foo (B b) = …
        foo (C c ∥ D d) = …


No, I don't think that's worth drawing up a proposal yet. I just want to
document the idea. Maybe it can inspire someone who's building their own
language or something.


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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Richard A. O'Keefe
There is another elementary alternative.  If you need to treat C and
D the same in just one place, you don't really have a problem.  If
you need to treat them the same in several places, do this:

data T a b c = A a | B b | C c | D c  -- existing type

data Which a b c = A' a | B' b | CD Bool c

which :: T a b c -> Which a b c
which (A a) = A' a
which (B b) = B' b
which (C c) = CD False c
which (D c) = CD True  c

then
    case which $ x of
      A' a ->
      B' b ->
      CD _ c -> ...

If you want to merge the C and D cases often, I like this approach,
otherwise the
    C c -> f c
    D c -> f c
    where f c = ...
approach is better.

_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
In reply to this post by MarLinn
Exactly! "C c | D d" looks super!


> > Hello, Li-yao! I mean this: https://wiki.haskell.org/MultiCase
> >  
> >> Hi Paul,
> >>
> >> This looks like the or-patterns proposal:
> >>
> >> https://github.com/ghc-proposals/ghc-proposals/pull/43
> >>
> >>  
>
> You can see on github that it's just "dormant". But the examples in
> this thread made me have an interesting, even more general idea: we
> have functions on term-level and type-level – why not on
> pattern-level?
>
> Here's a very rough draft of what I imagine:
>
> {-# LANGUAGE PatternFamilies, PatternKinds #-}
>
>
> data Dt a = A a | B a | C a | D a deriving ( Show )
>
> pattern (∥) ∷ (Pattern a → T) → (Pattern a → T) → (T → U) →
> (a → U) pattern (a ∥ _) f = f a
> pattern (_ ∥ b) f = f b
>
> infixl 2 pattern ∥
>  
> foo ∷ (Show a) ⇒ Dt a → String
> foo (A a) = …
> foo (B b) = …
> foo (C c ∥ D d) = …
>
>
> No, I don't think that's worth drawing up a proposal yet. I just want
> to document the idea. Maybe it can inspire someone who's building
> their own language or something.
>
>
> 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.
_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
In reply to this post by Richard A. O'Keefe
Hello, Richard.

As a result I did with "...where f c = ..." :) A way with "which" is
interesting but duplicates unique constructors (A -> A', B -> B').

Interesting, is F# can solve this problem with active pattern?

Pattern matching in Haskell does not seem enought flexible, for
example, if I have `data D = D a b c d`, how can I match it without
placeholders for `D` args? Something like `D...`? I need to write
`D _ _ _ _` if I want to match without to bind args, right?

I want to say, that may be (I'm not sure, I'm newbie in Haskell) active
patterns can solve this and many other problems, may be active-pattern
+ reflection. For last example, I create pattern `IsD` in place where
`D` is defined and use it - to be more independent on D args (D can be
record and I can use getters/lens only to access its args, so I need a
way to be similar independent from its args in pattern-matching too).

But again, I'm not sure about right approaches - I'm newbie yet.


===
Best regards, Paul

> There is another elementary alternative.  If you need to treat C and
> D the same in just one place, you don't really have a problem.  If
> you need to treat them the same in several places, do this:
>
> data T a b c = A a | B b | C c | D c  -- existing type
>
> data Which a b c = A' a | B' b | CD Bool c
>
> which :: T a b c -> Which a b c
> which (A a) = A' a
> which (B b) = B' b
> which (C c) = CD False c
> which (D c) = CD True  c
>
> then
>     case which $ x of
>       A' a ->
>       B' b ->
>       CD _ c -> ...
>
> If you want to merge the C and D cases often, I like this approach,
> otherwise the
>     C c -> f c
>     D c -> f c
>     where f c = ...
> approach is better.
>
> _______________________________________________
> 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.
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Clinton Mead
You can record match like so "x@D{}" but then you'll need someway to access the contents of "x" (if you're interested in the contents, that is).

On Fri, Jun 16, 2017 at 3:43 PM, Baa <[hidden email]> wrote:
Hello, Richard.

As a result I did with "...where f c = ..." :) A way with "which" is
interesting but duplicates unique constructors (A -> A', B -> B').

Interesting, is F# can solve this problem with active pattern?

Pattern matching in Haskell does not seem enought flexible, for
example, if I have `data D = D a b c d`, how can I match it without
placeholders for `D` args? Something like `D...`? I need to write
`D _ _ _ _` if I want to match without to bind args, right?

I want to say, that may be (I'm not sure, I'm newbie in Haskell) active
patterns can solve this and many other problems, may be active-pattern
+ reflection. For last example, I create pattern `IsD` in place where
`D` is defined and use it - to be more independent on D args (D can be
record and I can use getters/lens only to access its args, so I need a
way to be similar independent from its args in pattern-matching too).

But again, I'm not sure about right approaches - I'm newbie yet.


===
Best regards, Paul

> There is another elementary alternative.  If you need to treat C and
> D the same in just one place, you don't really have a problem.  If
> you need to treat them the same in several places, do this:
>
> data T a b c = A a | B b | C c | D c  -- existing type
>
> data Which a b c = A' a | B' b | CD Bool c
>
> which :: T a b c -> Which a b c
> which (A a) = A' a
> which (B b) = B' b
> which (C c) = CD False c
> which (D c) = CD True  c
>
> then
>     case which $ x of
>       A' a ->
>       B' b ->
>       CD _ c -> ...
>
> If you want to merge the C and D cases often, I like this approach,
> otherwise the
>     C c -> f c
>     D c -> f c
>     where f c = ...
> approach is better.
>
> _______________________________________________
> 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.
_______________________________________________
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.


_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Richard A. O'Keefe
In reply to this post by Baa
> Hello, Richard.
>
> As a result I did with "...where f c = ..." :) A way with "which" is
> interesting but duplicates unique constructors (A -> A', B -> B').

Yes, but if you *often* want to group constructors together, it's
still a good idea.  The alternative, which has already been suggested,
is to group them together in the original type, but you might want to
classify the alternatives in more than one way.

>
> Interesting, is F# can solve this problem with active pattern?

Probably.  See
https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/active-patterns
for details of active patterns in F#.
The syntax is seriously twisted.  You *can* associate
data with the partitions, but it's really not obvious.
If you want to classify something more than 7 ways F# is unhelpful.
F# active patterns are not entirely unlike view patterns
https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns
only stranger.

>
> Pattern matching in Haskell does not seem enought flexible, for
> example, if I have `data D = D a b c d`, how can I match it without
> placeholders for `D` args? Something like `D...`? I need to write
> `D _ _ _ _` if I want to match without to bind args, right?

Yes, but (a) in all seriousness, that's not much of a problem,
surely and (b) there is an alternative.  If you write instead

data D a b c d = D { f1 :: a, f2 :: b, f3 :: c, f4 :: d }

then you can abbreviate patterns like this:

f (D{}) = ()

g (D{f1 = x}) = x

If you have enough fields for counting the placeholders to be a
problem then you have enough fields that you really *ought* to be
naming them anyway.

The problem with making pattern matching overly flexible is that
people have to read and understand this stuff.  It's a bit like
regular expressions:  POSIX regular expressions can be implemented
to take linear time (by simulating an NDFA), but they are a bit
limited, whereas Perl regular expressions are very expressive
indeed, but they can all too easily take exponential time, and it
isn't easy for John and Jane Doe programmers to tell when that is
going to happen.

Generally speaking, before proposing language changes, it's
always a good idea to see if you can solve your problem by
factoring out common stuff into a new function (or type, or
typeclass) first.



_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Hiromi ISHII
In reply to this post by Clinton Mead
Hi cafe,

Here's another solution using lens (and prisms):

```
{-# LANGUAGE PatternSynonyms, RankNTypes, TemplateHaskell, ViewPatterns #-}
module Main where
import Control.Lens

data F = C Int | D Int | E String  Int | F Int | G String
       deriving (Read, Show, Eq, Ord)
makePrisms ''F

match = flip (^?)

main :: IO ()
main =
  case C 2 of
    (match (_C <|?> _D <|?> _E._2 <|?> _F) -> Just i) -> print i
    G s -> putStrLn s

infixl 8 <|?>

(<|?>) :: (Conjoined p, Applicative f) =>
          Traversing p f s t a b -> Over p f s t a b -> Over p f s t a b
(<|?>) = failing
```


> 2017/06/16 14:55、Clinton Mead <[hidden email]>のメール:
>
> You can record match like so "x@D{}" but then you'll need someway to access the contents of "x" (if you're interested in the contents, that is).
>
> On Fri, Jun 16, 2017 at 3:43 PM, Baa <[hidden email]> wrote:
> Hello, Richard.
>
> As a result I did with "...where f c = ..." :) A way with "which" is
> interesting but duplicates unique constructors (A -> A', B -> B').
>
> Interesting, is F# can solve this problem with active pattern?
>
> Pattern matching in Haskell does not seem enought flexible, for
> example, if I have `data D = D a b c d`, how can I match it without
> placeholders for `D` args? Something like `D...`? I need to write
> `D _ _ _ _` if I want to match without to bind args, right?
>
> I want to say, that may be (I'm not sure, I'm newbie in Haskell) active
> patterns can solve this and many other problems, may be active-pattern
> + reflection. For last example, I create pattern `IsD` in place where
> `D` is defined and use it - to be more independent on D args (D can be
> record and I can use getters/lens only to access its args, so I need a
> way to be similar independent from its args in pattern-matching too).
>
> But again, I'm not sure about right approaches - I'm newbie yet.
>
>
> ===
> Best regards, Paul
>
> > There is another elementary alternative.  If you need to treat C and
> > D the same in just one place, you don't really have a problem.  If
> > you need to treat them the same in several places, do this:
> >
> > data T a b c = A a | B b | C c | D c  -- existing type
> >
> > data Which a b c = A' a | B' b | CD Bool c
> >
> > which :: T a b c -> Which a b c
> > which (A a) = A' a
> > which (B b) = B' b
> > which (C c) = CD False c
> > which (D c) = CD True  c
> >
> > then
> >     case which $ x of
> >       A' a ->
> >       B' b ->
> >       CD _ c -> ...
> >
> > If you want to merge the C and D cases often, I like this approach,
> > otherwise the
> >     C c -> f c
> >     D c -> f c
> >     where f c = ...
> > approach is better.
> >
> > _______________________________________________
> > 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.
> _______________________________________________
> 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.
>
> _______________________________________________
> 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.
----- 石井 大海 ---------------------------
[hidden email]
筑波大学数理物質科学研究科
数学専攻 博士後期課程二年
----------------------------------------------


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

signature.asc (507 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Brandon Allbery
In reply to this post by Richard A. O'Keefe

On Fri, Jun 16, 2017 at 2:21 AM, <[hidden email]> wrote:
If you write instead

data D a b c d = D { f1 :: a, f2 :: b, f3 :: c, f4 :: d }

then you can abbreviate patterns like this:

f (D{}) = ()

As a special case, you can use the no-fields record pattern Cons {} with *any* constructor, regardless of whether it was defined with record syntax or whether it has parameters.

--
brandon s allbery kf8nh                               sine nomine associates
[hidden email]                                  [hidden email]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
> On Fri, Jun 16, 2017 at 2:21 AM, <[hidden email]> wrote:
>
> > If you write instead
> >
> > data D a b c d = D { f1 :: a, f2 :: b, f3 :: c, f4 :: d }
> >
> > then you can abbreviate patterns like this:
> >
> > f (D{}) = ()
> >  
>
> As a special case, you can use the no-fields record pattern Cons {}
> with *any* constructor, regardless of whether it was defined with
> record syntax or whether it has parameters.
>

Aha, I checked it, good.
_______________________________________________
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.
Baa
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Baa
In reply to this post by Richard A. O'Keefe
> > Interesting, is F# can solve this problem with active pattern?  
>
> Probably.  See
> https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/active-patterns
> for details of active patterns in F#.
> The syntax is seriously twisted.  You *can* associate
> data with the partitions, but it's really not obvious.
> If you want to classify something more than 7 ways F# is unhelpful.
> F# active patterns are not entirely unlike view patterns
> https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns
> only stranger.

view patterns are "active" too, sure while they are callable :)
Unfortunately I am not so familiar with both to compare them in detail.
Are they equal in capacity/in general or only partially? I mean, can
Haskell view patterns cover all possibilities of Active Patterns of F#?

> >
> > Pattern matching in Haskell does not seem enought flexible, for
> > example, if I have `data D = D a b c d`, how can I match it without
> > placeholders for `D` args? Something like `D...`? I need to write
> > `D _ _ _ _` if I want to match without to bind args, right?  
>
> Yes, but (a) in all seriousness, that's not much of a problem,
> surely and (b) there is an alternative.  If you write instead
>
> data D a b c d = D { f1 :: a, f2 :: b, f3 :: c, f4 :: d }
>
> then you can abbreviate patterns like this:
>
> f (D{}) = ()
>
> g (D{f1 = x}) = x
>
> If you have enough fields for counting the placeholders to be a
> problem then you have enough fields that you really *ought* to be
> naming them anyway.

That it is, good! Thanks for this hint!

> The problem with making pattern matching overly flexible is that
> people have to read and understand this stuff.  It's a bit like
> regular expressions:  POSIX regular expressions can be implemented
> to take linear time (by simulating an NDFA), but they are a bit
> limited, whereas Perl regular expressions are very expressive
> indeed, but they can all too easily take exponential time, and it
> isn't easy for John and Jane Doe programmers to tell when that is
> going to happen.

Sure, true.

> Generally speaking, before proposing language changes, it's
> always a good idea to see if you can solve your problem by
> factoring out common stuff into a new function (or type, or
> typeclass) first.
>

Sure, but there is another point of view here. Alternative is to have
flexible but elegant syntax embedded in language, instead of many-many
extensions for any possibility - they "fragment" language. But of course
this is controversial and ambiguous :-)

===
Best regards, Paul
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: MultiCase alternative

Brandon Allbery
On Fri, Jun 16, 2017 at 6:12 AM, Baa <[hidden email]> wrote:
Sure, but there is another point of view here. Alternative is to have
flexible but elegant syntax embedded in language, instead of many-many
extensions for any possibility - they "fragment" language. But of course
this is controversial and ambiguous :-)

The active patterns of F# that you mentioned can be seen as a counterargument :)

--
brandon s allbery kf8nh                               sine nomine associates
[hidden email]                                  [hidden email]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

_______________________________________________
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.
12
Loading...