I wonder of wherher the library needs some generalized zipWith-n functions.
For example, the below function is actually zipWith3,
but one list is by List and others are by List.All:
zip3with? : (triples : List (C Ă â Ă C)) â All.All ^eq triples â
All.All (\e â e > 0) $ map tuple32 triples â List Item
zip3with? [] _ _ = []
zip3with? ((p , e , d) â· triples) (d=p^e â·a eqs) (e>0 â·a restExps>0) =
item â· (zip3with? triples eqs restExps>0)
where
item = record{ ... }
So off the top of my head I'm struggling to come up with a generalised zipWith-n function which is both sufficiently general and easy to reason about. Do you have such an implementation?
I don't think zip3with is common or useful enough to warrant being included in the standard library.
Closing as I'm afraid I can't come up with a suitable zipWith-n function.
I think this ought to be doable using the code in #608
Edit: yep. uncurried version (_<$>_ is map over Sets using a level polymorphic endofunctor on Set l):
zw-aux : â n {ls} {as : Sets n ls} â
(Product n as â R) â
(Product n (List <$> as) â List R)
zw-aux 0 f as = []
zw-aux 1 f (as , _) = map (f â (_, tt)) as
zw-aux (suc n) f (as , ass) = zipWith _$_ fs as
where fs = zw-aux n (flip (curry f)) ass
How about
open import Level using (Level)
open import Function
open import Function.Nary.NonDependent
open import Data.Nat
open import Data.Product using (_Ă_; _,_; projâ; projâ) renaming (curry to curryâ; uncurry to uncurryâ)
open import Data.List using (List; []; _â·_; map) renaming (zipWith to zipWithâ)
variable
l : Level
R : Set l
zipWith : â n {ls} {as : Sets n ls} â
Arrows n as R â Arrows n (List <$> as) (List R)
zipWith zero f = []
zipWith (suc zero) f = map f
zipWith (suc (suc n)) f xsâ xsâ = zipWith (suc n) id (zipWithâ f xsâ xsâ)
or alternatively
zipWith : â n {ls} {as : Sets n ls} â
Arrows n as R â Arrows n (List <$> as) (List R)
zipWith zero f = []
zipWith (suc zero) f = map f
zipWith (suc (suc n)) f xsâ xsâ = zipWith (suc n) (uncurryâ f) (zipWithâ _,_ xsâ xsâ)
I like the second one better. I am puzzled because I tried my best and I really
could not see how to implement it.
Going to remove the v1.1 milestone for this as I don't think it's urgent.
Generic n-ary lift for applicatives following a discussion with @Zambonifofex
open import Category.Applicative using (RawApplicative) hiding (module RawApplicative)
module _ (Test : â {â} â Set â â Set â)
(raw-applicative : â â â RawApplicative (Test {â})) where
open import Data.Unit
open import Level using (_â_; Lift)
open import Data.Nat.Base
open import Data.Product
open import Data.Product.Nary.NonDependent
open import Function
open import Function.Nary.NonDependent
module App {â} = Category.Applicative.RawApplicative (raw-applicative â)
ProductÎș : â n {l} (as : Sets n (lreplicate n l)) â Set l
ProductÎș zero as = Lift _ â€
ProductÎș (suc n) (a , as) = a Ă ProductÎș n as
toProductÎș : â n {l} {as : Sets n (lreplicate n l)} â Product†n as â ProductÎș n as
toProductÎș zero _ = _
toProductÎș (suc n) (v , vs) = v , toProductÎș n vs
fromProductÎș : â n {l} {as : Sets n (lreplicate n l)} â ProductÎș n as â Product†n as
fromProductÎș zero _ = _
fromProductÎș (suc n) (v , vs) = v , fromProductÎș n vs
curryÎșâ : â n {l} {as : Sets n (lreplicate n l)} {r} {b : Set r} â
(ProductÎș n as â b) â as â b
curryÎșâ n f = curryâ€â n (f â toProductÎș n)
uncurryÎșâ : â n {l} {as : Sets n (lreplicate n l)} {r} {b : Set r} â
as â b â (ProductÎș n as â b)
uncurryÎșâ n f = uncurryâ€â n f â fromProductÎș n
sequenceA : â n {l} {as : Sets n (lreplicate n l)} â
ProductÎș n (Test <$> as) â Test (ProductÎș n as)
sequenceA zero p = App.pure p
sequenceA (suc n) (ta , p) = _,_ App.<$> ta App.â sequenceA n p
lift : â n {l} {R : Set l} {As : Sets n (lreplicate n l)} â
As â R â (Test <$> As) â Test R
lift n f = curryÎșâ n (λ ps â uncurryÎșâ n f App.<$> sequenceA n ps)