小编fir*_*dle的帖子

iteratee I/O在非功能语言中是否有意义?

在Haskell中,基于Iteratee的I/O似乎非常有吸引力.Iteratees是一种可组合,安全,快速的I/O方式,受功能语言中'fold'又称'reduce'功能的启发.基本上,如果你有一个遍历的想法是将遍历状态封装到一个所谓的"枚举器"中,它调用"iteratee",而"iteratee"又是一个函数,它返回一个值或一个更多数据的请求以及一个继续要调用的枚举器.因此,只有枚举器才知道遍历的状态,而迭代者知道如何处理数据并从中构建值.关于它的好处是迭代可以自动组合,其中一个迭代的输出被馈送到另一个迭代以产生更大的迭代.

那么,有两个问题:

  • 这个概念甚至可以用于其他语言,例如普通的面向对象语言,还是仅用于克服Haskell懒惰I/O的缺点?
  • 是否有其他语言的实际实现,特别是C#(因为这是我公司使用的)?(谷歌搜索在Scala中提到了一个iteratees;好吧,我现在对Scala不感兴趣).

c# iteration haskell

17
推荐指数
2
解决办法
1212
查看次数

理解Haskell中的结构共享

在Liu和Hudak撰写的"用箭头堵塞空间泄漏"一文中,声称这会导致O(n ^ 2)运行时行为(用于计算第n项):

 successors n = n : map (+1) (successors n)
Run Code Online (Sandbox Code Playgroud)

虽然这给了我们线性时间:

successors n = let ns = n : map (+1) ns
               in ns
Run Code Online (Sandbox Code Playgroud)

.这句话肯定是正确的,因为我可以使用GHCi轻松验证.但是,我似乎无法理解为什么,以及在这种情况下结构共享如何帮助.我甚至试图写出计算第三学期的两个扩展.

这是我尝试的第一个变体:

successors 1 !! 2
(1 : (map (+1) (successors 1))) !! 2
     (map (+1) (successors 1)) !! 1
     (map (+1) (1 : map (+1) (successors 1))) !! 1
     2 : (map (+1) (map (+1) (successors 1))) !! 1
         (map (+1) (map (+1) (successors 1))) !! 0
         (map (+1) (map (+1) (1 : …
Run Code Online (Sandbox Code Playgroud)

haskell lazy-evaluation

11
推荐指数
2
解决办法
480
查看次数

conduit和network-conduit:结合MonadResource和IO

我正在试验导管包.我还找到了network-conduit包,我试着建立一个简单的TCP客户端,它将文件的内容发送到套接字:

import Data.Conduit
import Data.Conduit.Binary
import Data.Conduit.Network
import Data.ByteString.Char8 (pack)

sendFile fileName appData = runResourceT $ 
   sourceFile fileName $$ appSink appData

main = runTCPClient (clientSettings 8000 (pack "localhost")) (sendFile "book.tex")
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为app sink不属于ResourceT:

[1 of 1] Compiling Main             ( Conduit2.hs, interpreted )

Conduit2.hs:9:63:
    Occurs check: cannot construct the infinite type: m0 = ResourceT m0
    Expected type: Application (ResourceT m0)
      Actual type: AppData (ResourceT m0) -> m0 ()
    In the return type of a call of `sendFile'
    In the second argument of …
Run Code Online (Sandbox Code Playgroud)

haskell conduit

5
推荐指数
1
解决办法
333
查看次数

避免递归中的模式匹配

考虑一下我用来解决欧拉问题58的代码:

diagNums = go skips 2
    where go (s:skips) x = let x' = x+s
                           in x':go skips (x'+1)

squareDiagDeltas = go diagNums
    where go xs = let (h,r) = splitAt 4 xs
                  in h:go r
Run Code Online (Sandbox Code Playgroud)

我不喜欢第二个函数中的模式匹配.它看起来比必要的复杂!这对我来说经常出现.在这里,splitAt返回一个元组,所以我必须先解构它才能递归.当我的递归本身返回我想要修改的元组时,相同的模式可能更令人讨厌.考虑:

f n = go [1..n]
    where go [] = (0,0)
          go (x:xs) = let (y,z) = go xs
                      in (y+x, z-x)
Run Code Online (Sandbox Code Playgroud)

与简单的递归相比:

f n = go [1..n]
    where go [] = 0
          go (x:xs) = x+go xs
Run Code Online (Sandbox Code Playgroud)

当然,这里的功能纯属无意义,可以用完全不同的更好的方式编写.但我的观点是,每次我需要通过递归回调多个值时,就会出现模式匹配的需要.

有没有办法避免这种情况,可能是通过使用Applicative或类似的东西?或者你会认为这种风格是惯用的吗?

haskell applicative

4
推荐指数
1
解决办法
244
查看次数

java.util.HashSet不遵守其规范吗?

作为一个相对的Java菜鸟,我很困惑,找出以下内容:

Point.java:

public class Point {
...
    public boolean equals(Point other) {
        return x == other.x && y == other.y;
    }
...
}
Run Code Online (Sandbox Code Playgroud)

Edge.java:

public class Edge {
    public final Point a, b;
    ...
    public boolean equals(Edge other) {
        return a.equals(other.a) && b.equals(other.b);
    }
...
}
Run Code Online (Sandbox Code Playgroud)

main snippet:private Set blockedEdges;

public Program(...) {
    ...
    blockedEdges = new HashSet<Edge>();

    for (int i = 0; ...) {
        for (int j = 0; ...) {

            Point p = new Point(i, j);              
            for (Point …
Run Code Online (Sandbox Code Playgroud)

java hashset

2
推荐指数
1
解决办法
58
查看次数

标签 统计

haskell ×4

applicative ×1

c# ×1

conduit ×1

hashset ×1

iteration ×1

java ×1

lazy-evaluation ×1