Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pattern matching and named argument in one

In haskell I can receive argument using pattern matching, which give me easy access to basic elements, but is more complicated to join them together

let id (hd:tl) = (hd:tl)

I can also receive it by name, but then it's more complicated to split object into basic elements.

let id list = ((head list):(tail list))

Can I have easy access to whole object and its components at the same function?

I think there should be something like

let id (hd:tl) as list = ...

By now I've figured out

let id (hd:tl) =
   let list = (hd:tl)
   in ...
like image 351
Jakub Kuszneruk Avatar asked Mar 20 '14 01:03

Jakub Kuszneruk


1 Answers

I think you're looking for the @ syntax:

let id list@(hd:tl) = ...

You can even get pretty complicated with it, as in this very contrived example:

> :set +m        -- Multi-line expressions in GHCi
> let f :: [[Int]] -> [Int]
|     f whole@[fstLst@(x:xs), sndLst@(y:ys)] =
|         length whole :
|         length fstLst + x :
|         length sndLst + y :
|         xs ++ ys
|     f _ = []
> f [[1..10], [11..20]]
[2,11,21,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20]

And since it's just a pattern matching construct, it obviously works for any type you have the constructors for.

like image 84
bheklilr Avatar answered Oct 17 '22 10:10

bheklilr