Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何在Haskell中压缩多个列表?_List_Haskell - Fatal编程技术网

List 如何在Haskell中压缩多个列表?

List 如何在Haskell中压缩多个列表?,list,haskell,List,Haskell,在pythonzip中,函数接受任意数量的列表并将它们压缩在一起 >>> l1 = [1,2,3] >>> l2 = [5,6,7] >>> l3 = [7,4,8] >>> zip(l1,l2,l3) [(1, 5, 7), (2, 6, 4), (3, 7, 8)] >>> 如何将haskell中的多个列表压缩在一起?看起来haskell中还有一个zip3()和zip4()函数。但zipn似乎很复杂

在python
zip
中,函数接受任意数量的列表并将它们压缩在一起

>>> l1 = [1,2,3]
>>> l2 = [5,6,7]
>>> l3 = [7,4,8]
>>> zip(l1,l2,l3)
[(1, 5, 7), (2, 6, 4), (3, 7, 8)]
>>> 

如何将haskell中的多个列表压缩在一起?

看起来haskell中还有一个
zip3
()和
zip4
()函数。但zipn似乎很复杂,因为它有强大的类型系统。我在研究过程中发现。

您可以转换列表:

>>> import Data.List
>>> transpose [l1,l2,l3]
[[1,5,7],[2,6,4],[3,7,8]]

这不是小事,但却是可行的。看见我不知道这是否成为了某个图书馆

这是一个更简单的例子。这张照片实际上可以剪切粘贴在这里:

{-# LANGUAGE MultiParamTypeClasses
           , FunctionalDependencies
           , FlexibleInstances
           , UndecidableInstances
           #-}

-- |
-- Module      :  Data.List.ZipWithN
-- Copyright   :  Copyright (c) 2009 wren ng thornton
-- License     :  BSD3
-- Maintainer  :  wren@community.haskell.org
-- Stability   :  experimental
-- Portability :  non-portable (MPTCs, FunDeps,...)
--
-- Provides a polyvariadic 'map'/'zipWith' like the @map@ in Scheme.
-- For more details on this style of type hackery, see:
--
--    * Chung-chieh Shan, /A polyvariadic function of a non-regular/
--      /type (Int->)^N ([]^N e)->.../
--      <http://okmij.org/ftp/Haskell/polyvariadic.html#polyvartype-fn>
----------------------------------------------------------------
module Data.List.ZipWithN (ZipWithN(), zipWithN) where

-- | This class provides the necessary polymorphism. It is only
-- exported for the sake of giving type signatures.
--
-- Because we can't do functor composition without a lot of noise
-- from newtype wrappers, we use @gr@ and @kr@ to precompose the
-- direct/list functor with the reader functor and the return type.
class ZipWithN a gr kr | kr -> gr a where
    _zipWithN :: [a -> gr] -> [a] -> kr

instance ZipWithN a b [b] where
    _zipWithN = zipWith ($)

instance ZipWithN b gr kr => ZipWithN a (b -> gr) ([b] -> kr) where
    _zipWithN = (_zipWithN .) . zipWith ($)


-- | Polyadic version of 'map'/'zipWith'. The given type signature
-- isn't terribly helpful or intuitive. The /real/ type signature
-- is:
--
-- > zipWithN :: {forall a}^N. ({a->}^N  r) -> ({[a]->}^N  r)
--
-- Note that the @a@ type variables are meta and so are independent
-- from one another, despite being correlated in N across all
-- repetitions.
zipWithN :: (ZipWithN a gr kr) => (a -> gr) -> [a] -> kr
zipWithN = _zipWithN . repeat
{-#语言多段类型类
,功能依赖性
,灵活的实例
,不可判定的实例
#-}
-- |
--模块:Data.List.ZipWithN
--版权所有:版权所有(c)2009雷恩·桑顿
--许可证:BSD3
--维护者:wren@community.haskell.org
--稳定性:实验性
--可移植性:不可移植(MPTC、FundeP等)
--
--提供一个多变量“map”/“zipWith”,与方案中的@map@类似。
--有关此类型hackery的更多详细信息,请参阅:
--
--*钟杰山/非正则函数的多变量函数/
--/type(Int->)^N([]^N e)->/
--      
----------------------------------------------------------------
模块Data.List.ZipWithN(ZipWithN(),ZipWithN)其中
--|此类提供了必要的多态性。只是
--为了给出类型签名而导出。
--
--因为我们不能在没有大量噪音的情况下合成函子
--从newtype包装器中,我们使用@gr@和@kr@预合成
--具有读取器函子和返回类型的直接/列表函子。
类ZipWithN gr kr | kr->gr a where
_zipWithN::[a->gr]->[a]->kr
实例ZipWithN a b[b]其中
_zipWithN=zipWith($)
实例ZipWithN b gr kr=>ZipWithN a(b->gr)([b]->kr)其中
_zipWithN=(zipWithN.)。zipWith(美元)
--|多元版本的“地图”/“zipWith”。给定的类型签名
--不是很有帮助,也不是很直观。/real/type签名
--是:
--
-->zipWithN::{forall a}^N.({a->}^N r)->({[a]->}^N r)
--
--注意@a@type变量是元变量,因此是独立的
--尽管在所有的研究中都与N相关
--重复。
zipWithN::(zipWithN a gr kr)=>(a->gr)->[a]->kr
zipWithN=_zipWithN。重复

如果您刚刚开始学习Haskell,请将理解它的时间推迟一段时间:)

可以通过使用来实现对zip的概括。由于新类型的包装/解包,使用起来有点不舒服,但是如果你正在做一些用
zipWithn
无法完成的事情,对于相当小的n,你可能已经达到了足够高的抽象级别,在那里无论如何都不存在符号痛苦

类型为
ziplista
,其应用程序实例将列表压缩在一起。例如:

(+) <$> ZipList [1,2] <*> ZipList [3,4] == ZipList [4,6]

应用表示法是一种非常强大和通用的技术,它的范围比一般的压缩要广得多。有关应用程序符号的详细信息,请参阅。

如果所有数据的类型相同,则可以执行以下操作:

import Data.List (transpose)

zipAllWith :: ([a] -> b) -> [[a]] -> [b]
zipAllWith _ []  = []
zipAllWith f xss = map f . transpose $ xss

zipAll = zipAllWith id
例如:

> zipAll [[1, 2, 3], [4, 5, 6], [7, 8]]
[[1,4,7],[2,5,8],[3,6]]

对于特定数量的列表,您可以这样做:

> let l1 = [1,2,3]
> let l2 = "abc"
> let l3 = [10.0, 11.0, 12.0]
> let l4 = [True, False, False]

> [ (e1,e2,e3,e4) | (((e1,e2),e3),e4) <- zip (zip (zip l1 l2) l3) l4 ]
[(1,'a',10.0,True),(2,'b',11.0,False),(3,'c',12.0,False)]
>让l1=[1,2,3]
>让l2=“abc”
>设l3=[10.0,11.0,12.0]
>设l4=[真,假,假]
>[(e1,e2,e3,e4)|((e1,e2,e3),e4):

{-#语言并行列表comp}

[(x,y)|x通用化压缩实际上非常简单。您只需为
ZipList
编写专门版本的
Applicative
组合器即可:

z :: [a -> b] -> [a] -> [b]
z = zipWith ($)

infixl 4 `z`
现在,您可以根据需要压缩任意多个列表:

f <$> xs `z` ys `z` zs

我认为这可能是建议的最不优雅的解决方案,但为了完整性起见,应该补充一点,即使用模板Haskell可以实现这些功能

事实上,我认为Haskell论文的原始模板(文本中的搜索zipn)中包含了这一点:

但我认为代码实际上从未起过作用,请看: (未实现模式切片)

2003年没有实施,但今天仍然没有实施: (不支持模式切片)

但是,zipWithN有一个使用模板haskell的实现:

我已验证它与此测试程序配合使用:

{-# LANGUAGE TemplateHaskell #-}
import Zipn

main = do
    let l1 = [1,2,3]
    let l2 = [5,6,7]
    let l3 = [7,4,8]
    print $ $(zipWithN 3) (,,) l1 l2 l3
在Zipn模块中,我粘贴了Zipn,为了清晰起见,我刚刚重命名了zipWithN(记得在顶部添加pragma TemplateHaskell)。请注意,N实际上在这里被harcoded了两次,因为我必须将
(,)
作为“with”函数。您必须根据N更改逗号的数量

(,)
代表
\abc->(a,b,c)


我猜是有很好的模板Haskell技能的人(这不是我现在的情况)可以使用模板Haskell直接生成zipN。

zip3的相应示例:
zip3
:你是说在Haskell中这是不可能的吗?我不知道。也许其他人知道一个诀窍。但我认为机会很低,因为邮件列表上没有一个好的答案,标准库已经实现了所有这些zip2,zip3 e相反,tc.函数…广义的
zipWithN
:Data.List上升到
zip7
。可以说元组中的7项对于一个易于理解、可维护的程序来说已经太多了。只有当所有参数都具有相同的类型时才起作用,这也是为什么实现通用的zipN似乎如此困难的原因行为上的偏差:转置[[1,2,3],[4,5,6,7]=>[[1,4],[2,5],[3,6],[7]。[zip不包括最后一个元素。但显然,这是一个赢家!肯定会加入我的工具箱。我编写此函数是为了避免列表长度不匹配时出现不同的行为:
zipLists list=takeWhile(\x->length x==length list)$transpose list
我一个字也听不懂。我只有哈斯克尔的基本知识。你能把这个函数提取出来吗
{-# LANGUAGE ParallelListComp #-}

[(x,y) | x <- [1..3]
       | y <- ['a'..'c']
       ]

==> [(1,'a'),(2,'b'),(3,'c')]
z :: [a -> b] -> [a] -> [b]
z = zipWith ($)

infixl 4 `z`
f <$> xs `z` ys `z` zs
repeat f `z` xs `z` ys `z` zs
{-# LANGUAGE TemplateHaskell #-}
import Zipn

main = do
    let l1 = [1,2,3]
    let l2 = [5,6,7]
    let l3 = [7,4,8]
    print $ $(zipWithN 3) (,,) l1 l2 l3