小编mer*_*ict的帖子

Data.Map实现中的错误?

我一直在说我的东西绊倒猜测是一个错误Data.Map,但也很可能在我的Haskell知识的错误.希望有人能澄清它是什么:)

请参考这个要点.我正在将循环链表结构序列化为字节流.对于任何给定节点,形式如下:

data Node = Node
  { val  :: Word8
  , next :: Node
  }
Run Code Online (Sandbox Code Playgroud)

我希望它被序列化为一对字节:表示第一个字节val,第二个字节表示next可以定位的字节流中的偏移量.例如,我希望:

let n0 = Node 0 n1
    n1 = Node 1 n0
Run Code Online (Sandbox Code Playgroud)

被序列化为[0, 1, 1, 0].没什么大不了.

这里稍微棘手的部分是我正在利用MonadFix实例RWST来"绑定"字节流偏移:我维护一个从节点到偏移的映射,在序列化期间填充映射,但也引用了映射中没有的映射必然存在,直到序列化完成.

当地图实现Data.HashMap.Lazy(来自无序容器)时,这非常有用.但是,当实现是通常的Data.Map(从容器)时,程序堆栈溢出 - 没有双关语意图 - Map尝试无限地比较两个节点使用(==).

所以我的问题是:这是一个错误Data.Map,或者我对这些结构在存在mfix缺陷时应该如何表现的假设?

containers haskell monadfix tying-the-knot

16
推荐指数
1
解决办法
533
查看次数

为什么hGetBuf,hPutBuf等会分配内存?

在做一些简单的基准测试的过程中,我遇到了让我感到惊讶的事情.从Network.Socket.Splice获取此片段:

hSplice :: Int -> Handle -> Handle -> IO ()
hSplice len s t = do
  a <- mallocBytes len :: IO (Ptr Word8)
  finally
    (forever $! do
       bytes <- hGetBufSome s a len
       if bytes > 0
         then hPutBuf t a bytes
         else throwRecv0)
    (free a)
Run Code Online (Sandbox Code Playgroud)

人们预计,hGetBufSomehPutBuf在这里就不需要分配内存,因为它们写进去,并从预分配的缓冲区读取.该文件似乎支持这一直觉了......但很可惜:

                                        individual     inherited
COST CENTRE                            %time %alloc   %time %alloc      bytes

 hSplice                                 0.5    0.0    38.1   61.1       3792
  hPutBuf                                0.4    1.0    19.8   29.9   12800000
   hPutBuf'                              0.4 …
Run Code Online (Sandbox Code Playgroud)

io profiling haskell

14
推荐指数
1
解决办法
1280
查看次数

hashCode和equals for Collections.unmodifiableCollection()

Collections类有很多的静态辅助方法来提供只读视图各种集合类型,例如unmodifiableSet(),unmodifiableList()等等.对于这些视图对象中,hashCode()equals()方法前调用底层集合......随着一个奇怪的例外:unmodifiableCollection().

JavaDoc 明确指出:

返回的集合并没有将hashCode并传递给底层集合等于操作,但依靠ObjectequalshashCode方法.在后备集合是集合或列表的情况下,这对于保留这些操作的合同是必要的.

我的问题:wtf是这个在谈论?如果支持集合是集合或列表,我希望行为与unmodifiableSet()和一致unmodifiableList().怎么会违反hashCode/equals合约?

java collections unmodifiable

13
推荐指数
1
解决办法
1677
查看次数

折叠flatMap/bind在一系列函数上(又名Name That Combinator!)

在编写简单的RPN计算器的过程中,我有以下类型的别名:

type Stack = List[Double]
type Operation = Stack => Option[Stack]
Run Code Online (Sandbox Code Playgroud)

...我写了一个好奇的Scala代码:

val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
Run Code Online (Sandbox Code Playgroud)

这将获取stack值的初始值并应用operations该堆栈的列表.每个操作都可能失败(即产生一个Option[Stack]),所以我对它们进行排序flatMap.对我来说有些不同寻常的事情(在我看来)是我折叠了一系列monadic函数,而不是折叠数据列表.

我想知道是否有一个标准函数可以捕获这种"折叠绑定"行为.当我试图玩"Name That Combinator"游戏时,Hoogle通常是我的朋友,所以我在Haskell尝试了相同的心理锻炼:

foldl (>>=) (Just stack) operations
Run Code Online (Sandbox Code Playgroud)

这里的类型是:

foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

所以我的神秘foldl (>>=)组合器的类型,在制作类型foldl(>>=)排队之后,应该是:

mysteryCombinator :: Monad m => …
Run Code Online (Sandbox Code Playgroud)

haskell scala combinators

12
推荐指数
1
解决办法
1937
查看次数

任何方法可以恢复足够的懒惰以打结monad结?

我想写一个光滑的代码(通过打结来节省我很多时间来实现).它大致是这样的,

n <- myinstr n x
Run Code Online (Sandbox Code Playgroud)

在理论上,myinstr应该运行x以获得一个价值,这将成为n.myinstrStatemonad 中运行,将n进入状态,但这不会影响x计算.

我尝试过使用DoRec和实现的mfix,

instance Monad  => MonadFix (MyMonad ) where
    mfix f = fix (\mx -> mx >>= f)
Run Code Online (Sandbox Code Playgroud)

事情冻结了.有没有任何方法可以修复我的代码(或者第一次正确设计它的方法),还是应该写一些更直接的东西?

monads haskell monadfix tying-the-knot

11
推荐指数
1
解决办法
360
查看次数

调试不必要的严格性?

我有一个问题,我不知道如何推理.我只是想问一下是否有人可以帮助我解决具体问题,但我突然意识到我可以提出一个更普遍的问题,希望能得到一个更好的一般性理解.希望.所以这里:

当你的程序太懒,通常很明显,因为你最终会遇到像空间泄漏这样的明显问题.我有相反的问题:我的程序太严格了.我想 ,并发现某些事情,我试图这样做会以某种方式打败我需要的懒惰.所以我的一般问题是,如何调试不必要的严格性?


为了完整起见,这是我的具体情况:我在RWS,编写器组件填充地图,阅读器组件观察该地图的最终状态.在我完成填充之前,我不能对这张地图做任何严格的事情.在地图中查找值似乎没有问题,例如:

do
  m <- ask
  val <- m ! key
  doSomething val -- etc.
Run Code Online (Sandbox Code Playgroud)

但是(!)没有使用error,我更愿意使用我的monad失败fail.所以我想做类似以下的事情:

do
  m <- ask
  maybe
    (fail "oh noes")
    (doSomething)
    (lookup key m)
Run Code Online (Sandbox Code Playgroud)

这导致我的程序<<loop>>,我不明白.在我看来,这不应该比使用更严格(!),但显然我错了......

haskell lazy-evaluation strictness tying-the-knot

11
推荐指数
1
解决办法
344
查看次数

斯卡拉的letrec?("打结"的不可改变的方式?)

假设我有一个像这样的愚蠢的小案例类:

case class Foo(name: String, other: Foo)
Run Code Online (Sandbox Code Playgroud)

我如何定义ab不可改变这样a.otherb,而且b.othera?scala是否提供了"打结"的方法?我想做这样的事情:

val (a, b): (Foo, Foo) = (Foo("a", b), Foo("b", a)) // Doesn't work.
Run Code Online (Sandbox Code Playgroud)

可能性

在Haskell中,我会这样做:

data Foo = Foo { name :: String, other :: Foo }

a = Foo "a" b
b = Foo "b" a
Run Code Online (Sandbox Code Playgroud)

绑定到ab包含在同一let表达式中或顶层的绑定.

或者,在不滥用Haskell的自动化letrec功能的情况下:

(a, b) = fix (\ ~(a', b') -> Foo "a" b', Foo "b" …
Run Code Online (Sandbox Code Playgroud)

scala letrec tying-the-knot

10
推荐指数
1
解决办法
656
查看次数

替换泛型Java方法的非法下限?

我想做以下事情:

public class ImmutableList<T> {
  public <U super T> ImmutableList<U> add(U element) { ... }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,给定一个不可变列表T,你可以U在列表中添加任何一个以产生一个不可变列表U,其约束U必须是一个超类型T.例如

  • 我可以将猴子添加到猴子列表中,产生一个新的猴子列表;
  • 我可以将一个人添加到猴子列表中,产生一个新的原始人名单(可能是猴子和人类的最小上限);
  • 我可以在一个原始人名单中添加一块岩石,产生一个新的清单Object(假设岩石和原始人不共享其他共同的祖先).

这在理论上听起来很棒,但是U根据JLS ,下限是不合法的.我可以写:

public class ImmutableList<T> {
  public ImmutableList<T> add(T element) { ... }
  public static <U> ImmutableList<U> add(ImmutableList<? extends U> list, U element) { ... }
}
Run Code Online (Sandbox Code Playgroud)

以这种方式,编译器将正确地推断列表的元素类型和U我们想要添加的最小上限.这是合法的.它也很糟糕.相比:

// if 'U super T' were legal
list.add(monkey).add(human).add(rock);

// assuming 'import static ImmutableList.add'
add(add(add(list, …
Run Code Online (Sandbox Code Playgroud)

java generics type-inference lower-bound

7
推荐指数
1
解决办法
282
查看次数

蛋糕模式中显式类型自引用的有用性

似乎Scala的显式类型自引用最常见的用法是" Cake模式 ",其中模块的依赖项声明如下:

class Foo { this: A with B with C =>
  // ...
}
Run Code Online (Sandbox Code Playgroud)

通常,暂时忽略蛋糕模式A,B并且C可以引用任何类型级别的东西,例如类型参数:

class Outer[A, B, C] {
  class Inner { this: A with B with C =>
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

......或抽象类型的成员:

class Outer {
  type A
  type B
  type C
  class Inner { this: A with B with C =>
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

在这些情况中,我们都不能写abstract class Inner extends A with B with C …

scala cake-pattern

7
推荐指数
1
解决办法
1112
查看次数

State和其他MTL monad的应用实例?

查看文档Control.Applicative,我注意到它们具有某些monad的实例声明(例如IO,Maybe特别是ST),但是没有MTL monad的实例,例如StateRWS.相反,它看起来像是WrappedMonad定义了一个通用类型,我猜测它是涵盖所有其他情况.

所以这是我的问题:

  1. 为什么没有ApplicativeMTL monad的实例?到目前为止,我自己能够找到的最好的答案是一个三年前的帖子,有人实现了这些实例,并被忽略了.

  2. 有什么处理WrappedMonad?我在Reddit上发现了一篇简短解释的帖子,但我觉得我对如何使用它很困惑.

最终我希望能够以State一种适用的方式使用(如推荐的那样),但如果我不得不用WrappedMonad数据构造函数丢弃我的代码,那么它似乎不是一个胜利.我也可以不理会WrappedMonad完全,并定义Applicative实例自己,是为做了同样的方式IO,ST等等:在以下方面returnap......但似乎愚蠢的为好.

haskell state-monad applicative

6
推荐指数
1
解决办法
1014
查看次数

Put的MonadFix实例

一个简单的问题,我希望:binary包定义了两种类型,GetPut.前者本质上是一个州的monad,而后者本质上是一个作家.这两个国家和作家有合理的MonadFix情况下,所以我期待GetPut也.

Get确实.Put没有.那么,是否可以MonadFixPut(真的PutM)定义一个合适的实例?

一个更普遍的问题是:通常如何验证类型类实例是否真正满足该类型类的规律?

haskell typeclass monadfix

6
推荐指数
1
解决办法
259
查看次数

Rand monad的MonadFix实例

我想用System.Random.MWC.Monad中的 Rand monad生成无限的数字流.如果只有这个monad的MonadFix实例,或者像这样的实例:

instance (PrimMonad m) => MonadFix m where
     ...
Run Code Online (Sandbox Code Playgroud)

然后人们可以写:

runWithSystemRandom (mfix (\ xs -> uniform >>= \x -> return (x:xs)))
Run Code Online (Sandbox Code Playgroud)

虽然没有一个.

我正在浏览MonadFix文档,但我没有看到实现此实例的明显方法.

random monads haskell monadfix

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