小编Dan*_*ton的帖子

惯用效率高的Haskell追加?

List和cons运算符(:)在Haskell中非常常见.缺点是我们的朋友.但有时我想添加到列表的末尾.

xs `append` x = xs ++ [x]
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这不是实施它的有效方式.

我在Haskell中写了Pascal的三角形,但我不得不使用++ [x]反成语:

ptri = [1] : mkptri ptri
mkptri (row:rows) = newRow : mkptri rows
    where newRow = zipWith (+) row (0:row) ++ [1]
Run Code Online (Sandbox Code Playgroud)

imho,这是一个可爱的可读Pascal的三角形和所有,但反成语让我烦恼.有人可以向我解释(并且,理想情况下,指向一个很好的教程)关于您想要有效追加到最后的情况下的惯用数据结构吗?我希望这个数据结构及其方法具有近似列表般的美感.或者,或者,向我解释为什么这种反成语对于这种情况实际上并不坏(如果你认为是这种情况).


[编辑]我最喜欢的答案是Data.Sequence,它确实具有"近似列表般的美丽".不确定我对操作所要求的严格程度.随时欢迎进一步的建议和不同的想法.

import Data.Sequence ((|>), (<|), zipWith, singleton)
import Prelude hiding (zipWith)

ptri = singleton 1 : mkptri ptri

mkptri (seq:seqs) = newRow : mkptri seqs
    where newRow = zipWith (+) seq (0 <| seq) |> 1 …
Run Code Online (Sandbox Code Playgroud)

performance haskell linked-list append idiomatic

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

哈斯克尔分部

我在Haskell中创建了一个函数,它只将列表中的evens减半,我遇到了问题.当我运行编译器时,它抱怨你不能执行int的划分,并且我需要一个小数int类型声明.我已经尝试将类型声明更改为float,但这只是生成了另一个错误.我已经在下面包含了该函数的代码,并希望获得任何形式的帮助.

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x/2:halfEvens xs
Run Code Online (Sandbox Code Playgroud)

谢谢你的阅读.

haskell division

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

没有arr的箭头

如果我们将对类别的理解限制Category为Haskell中的常用类:

class Category c where
  id :: c x x
  (>>>) :: c x y -> c y z -> c x z
Run Code Online (Sandbox Code Playgroud)

那么让我们说a ArrowCategory另外一个:

class Category c => Arrow c where
  (***) :: c x y -> c x' y' -> c (x,x') (y,y')
  (&&&) :: c x y -> c x y' -> c x (y,y')
Run Code Online (Sandbox Code Playgroud)

我们可以很容易地推导出:

first :: c x y -> c (x,z) (y,z)
first a = a *** id

second …
Run Code Online (Sandbox Code Playgroud)

haskell arrows category-theory

24
推荐指数
1
解决办法
541
查看次数

在类型级别未定义

通常当我正在使用Haskell代码时,我会使用类型注释来解决问题undefined.

foo :: String -> Int
foo = undefined
Run Code Online (Sandbox Code Playgroud)

是否存在类型级别的"未定义",我可以以类似的方式使用它?

(理想情况下,结合一种注释)

type Foo :: * -> *
type Foo = Undefined
Run Code Online (Sandbox Code Playgroud)

在同一个线程上进一步思考:有没有办法为这样创建的类型存根类型化实例?比以下理论方法更简单的方法是什么?

instance Monad Foo where
  return = undefined
  (>>=) = undefined
Run Code Online (Sandbox Code Playgroud)

haskell types undefined ghc type-kinds

23
推荐指数
2
解决办法
1040
查看次数

折叠,功能构成,单子和懒惰,哦,我的?

我很困惑.我可以这样写:

import Control.Monad

main = print $ head $ (foldr (.) id [f, g]) [3]
  where f = (1:)
        g = undefined
Run Code Online (Sandbox Code Playgroud)

而输出是1.这是有道理的,因为它减少到:

main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用模糊相似的monadic技术,它不会起作用:

import Control.Monad

main = print $ (foldr (<=<) return [f, g]) 3
  where f …
Run Code Online (Sandbox Code Playgroud)

monads haskell fold function-composition

22
推荐指数
2
解决办法
891
查看次数

Data.Vector会替换Data.Sequence吗?

我一直很喜欢Data.Sequence.但是,由于我一直在学习Data.Vector,它似乎可以做Data.Sequence可以做的一切,但更好,再加上它可以做更多的东西.我们应该弃用Data.Sequence并讲道Data.Vector吗?在Data.Vector上使用Data.Sequence有什么好的理由吗?

haskell vector sequence

20
推荐指数
1
解决办法
2047
查看次数

Scala的Cake Pattern可以在Haskell中实现吗?

在Scala中使用许多较新的语言特性,可以实现可组合的组件系统,并使用所谓的Cake Pattern创建组件,Martin Odersky在可扩展组件抽象论文中以及最近的演讲中描述了这种模式.

Cake Pattern中使用的一些Scala功能具有相应的Haskell功能.例如,Scala implicits对应于Haskell类型类,Scala的抽象类型成员似乎对应于Haskell的关联类型.这让我想知道Cake Pattern是否可以在Haskell中实现以及它看起来像什么.

Cake模式可以在Haskell中实现吗?Scala功能在这样的实现中对应哪些Haskell功能?如果Cake模式无法在Haskell中实现,那么哪些语言功能可能无法实现?

haskell module cake-pattern

20
推荐指数
1
解决办法
1133
查看次数

没有Prelude的ghci会话

这个问题出现在#haskell irc chat上:

如何在不导入前奏的情况下启动ghci?

可能的答案显而易见:

ghci -XNoImplicitPrelude,或加载文件 import Prelude ()

后者似乎有效,而前者则不然.但是,import Prelude ()从Prelude导入声明的实例,对吧?有没有更好的方法来创建一个ghci会话而不加载Prelude?

haskell ghci

19
推荐指数
2
解决办法
1802
查看次数

主方法中的Scala App val初始化

我有一些代码:

object Main extends App
{
    val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r

    override def main (args:Array[String])
    {
        // Why is NameTemplate null here?
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么NameTemplate不在main方法中初始化?

null program-entry-point scala

19
推荐指数
2
解决办法
2930
查看次数

使用Cont从未来和过去获取值

我正在Haskell写一个brainfuck解释器,我想出了一个我认为对程序非常有趣的描述:

data Program m = Instruction (m ()) (Program m)
               | Control (m (Program m))
               | Halt
Run Code Online (Sandbox Code Playgroud)

但是,将brainfuck程序的文本表示解析为此数据类型是很棘手的.尝试正确解析方括号时会出现问题,因为有一些结点可以使Instruction循环中的最终内容Control再次链接到循环.

更多初步信息.有关所有详细信息,请参阅github repo上的此版本.

type TapeM = StateT Tape IO
type TapeP = Program TapeM
type TapeC = Cont TapeP

branch :: Monad m => m Bool -> Program m -> Program m -> Program m
branch cond trueBranch falseBranch =
  Control ((\b -> if b then trueBranch else falseBranch) `liftM` cond)

loopControl :: TapeP -> TapeP -> …
Run Code Online (Sandbox Code Playgroud)

monads continuations haskell monadfix tying-the-knot

19
推荐指数
1
解决办法
1441
查看次数