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
Haskell 列表'dist'函数的应用分发服务器_Haskell - Fatal编程技术网

Haskell 列表'dist'函数的应用分发服务器

Haskell 列表'dist'函数的应用分发服务器,haskell,Haskell,我想我从中复制了以下dist函数: 本文以以下内容作为该功能的开头: 你注意到序列和转置现在看起来很相似吗? 区分这两个程序的细节由 从它们的类型中选择编译器。两者都是应用程序的实例 名单分发者 但是,我得到以下编译时错误: ghci> :l ApplicativePaper.hs [1 of 1] Compiling Main ( ApplicativePaper.hs, interpreted ) ApplicativePaper.hs:12:20:

我想我从中复制了以下
dist
函数:

本文以以下内容作为该功能的开头:

你注意到序列和转置现在看起来很相似吗? 区分这两个程序的细节由 从它们的类型中选择编译器。两者都是应用程序的实例 名单分发者

但是,我得到以下编译时错误:

ghci> :l ApplicativePaper.hs
[1 of 1] Compiling Main             ( ApplicativePaper.hs, interpreted )

ApplicativePaper.hs:12:20:
    Could not deduce (a ~ f a)
    from the context (Applicative f)
      bound by the type signature for
                 dist :: Applicative f => [f a] -> f [a]
      at ApplicativePaper.hs:10:9-39
      `a' is a rigid type variable bound by
          the type signature for dist :: Applicative f => [f a] -> f [a]
          at ApplicativePaper.hs:10:9
    Relevant bindings include
      vs :: [f a] (bound at ApplicativePaper.hs:12:9)
      v :: f a (bound at ApplicativePaper.hs:12:7)
      dist :: [f a] -> f [a] (bound at ApplicativePaper.hs:11:1)
    In the first argument of `(:)', namely `v'
    In the expression: (:) v (dist vs)
Failed, modules loaded: none.

请让我知道我做错了什么。此外,请提供此函数的直观说明。

在本文中,第4页上定义的双括号
〚f u1…un
纯f u1…un
相同

文本中
dist
的定义如下

dist :: Applicative f ⇒ [f a] → f [a ]
dist []       = 〚 [] 〛
dist (v : vs) = 〚 (:) v (dist vs) 〛
将其他符号翻译成Haskell,并替换
〚〛
的定义,结果是

dist :: Applicative f => [f a] -> f [a ]
dist []       = pure []
dist (v : vs) = pure (:) <*> v <*> (dist vs)
dist::Applicative f=>[fa]->f[a]
dist[]=纯[]
距离(v:vs)=纯(:)v(距离vs)

错误的括号。Conor McBride和Ross Paterson使用所谓的习惯用法括号。以下是您的虚拟语法定义(但它可能是通过Strathclyde Haskell增强编译的,我不确定):

(| f x y z |)
阐述到
纯f x y z
。所以
dist
的定义是正确的

dist :: Applicative f => [f a] -> f [a]
dist  []      = pure []
dist (v : vs) = (:) <$> v <*> dist vs -- f <$> x == pure f <*> x
只是它需要一个monad而不是applicative

还有一个
dist
的泛化,由
Traversable
typeclass提供:

sequenceA :: Applicative f => t (f a) -> f (t a)
所以这里有一些
t
(它既是
函子
又是
可折叠的
),而不是
[]

这是对
序列的描述

-- | Evaluate each action in the sequence from left to right,
-- and collect the results.
这是非常详尽的。比如说

main = dist [print 3, print 4, print 5]
main = do
    print $ dist_ [Just 3, Just 4, Just 5]
    print $ dist_ [Nothing, Just 3]
印刷品

3
4
5
Just ()
Nothing
Just [3,4,5]
Nothing
由于每个monad都是一个应用程序,
dist
在这里与IO monad一起正常工作。然而,没有必要在这里收集结果。这就是为什么有
序列
函数,它返回
()
作为结果

很容易定义距离:

dist_ :: Applicative f => [f a] -> f ()
dist_  []      = pure ()
dist_ (v : vs) = v *> dist_ vs
因此,您只需执行列表中的所有操作

比如说

main = dist [print 3, print 4, print 5]
main = do
    print $ dist_ [Just 3, Just 4, Just 5]
    print $ dist_ [Nothing, Just 3]
印刷品

3
4
5
Just ()
Nothing
Just [3,4,5]
Nothing
因为

Just smth1 *> Just smth2 == Just smth2
Nothing    *> Just smth2 == Nothing
dist
为这一机制添加的唯一功能是收集结果

所以

印刷品

3
4
5
Just ()
Nothing
Just [3,4,5]
Nothing

另外,看一下。

或简单的
dist(v:vs)=(:)v dist vs
@AaditMShah虽然这是正确的,但通过
pure
的定义更为一致:用
pure
提升“列表”的第一个元素,然后用
连接所有内容。那样的话,
〚【】【】
是完全合理的。