小编And*_*ewC的帖子

foldl是尾递归的,那么foldr如何比foldl运行得更快呢?

我想测试foldl vs foldr.从我所看到的,你应该使用foldl over foldr,因为尾部递归优化.

这是有道理的.但是,运行此测试后,我很困惑:

foldr(使用时间命令时需要0.057秒):

a::a -> [a] -> [a]
a x = ([x] ++ )

main = putStrLn(show ( sum (foldr a [] [0.. 100000])))
Run Code Online (Sandbox Code Playgroud)

foldl(使用time命令时需要0.089s):

b::[b] -> b -> [b]
b xs = ( ++ xs). (\y->[y])

main = putStrLn(show ( sum (foldl b [] [0.. 100000])))
Run Code Online (Sandbox Code Playgroud)

很明显,这个例子很简单,但我很困惑为什么foldr击败foldl.这不应该是foldl获胜的明显案例吗?

optimization haskell tail-recursion combinators fold

68
推荐指数
4
解决办法
2万
查看次数

我教ghci来编译我的StackOverflow帖子.我可以让它更光滑吗?

Haskell Stack Overflow布局预处理器

module StackOverflow where  -- yes, the source of this post compiles as is
Run Code Online (Sandbox Code Playgroud)

如果您想先玩这个(1/2向下),请跳到下面的操作以使其正常工作.如果我稍微
停下来,你会跳到我想要的东西,你只想找到我正在寻求的帮助.

TLDR问题摘要:

  1. 我可以使用ghci将文件名完成添加到:so我在我定义的命令中ghci.conf吗?
  2. 我可以以某种方式定义一个ghci命令来返回编译代码而不是返回一个ghci命令,或者ghci是否有更好的方法让我将Haskell代码作为特定于文件扩展名的预处理器插入,因此:l可以用于.hs.lhs像往常一样的文件,但使用我的手写预处理器的.so文件?

背景:

Haskell支持.lhs源文件中的文字编程,有两种方式:

  • 乳胶风格\begin{code}\end{code}.
  • Bird track:Code开头>,其他任何东西都是评论.
    代码和注释之间必须有一个空行(以防止意外误操作>).

Bird不跟踪类似于StackOverflow代码块的规则声音吗?

参考文献: 1. 将.ghci手册 2. GHCI haskellwiki 3. 关于尼尔·米切尔的博客:{,并:}在.ghci

预处理器

我喜欢在文本编辑器中编写SO答案,我喜欢发表一个包含有效代码的帖子,但最后还是>在发布之前我必须编辑的注释块或者s,这不那么有趣.

所以,我自己写了一个预处理器.

  • 如果我在代码块中粘贴了一些ghci,它通常以*或开头:. …

haskell ghci

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

值在哪里适合Hask类别?

所以我们有Hask类别,其中:

  • 类型是类别的对象
  • 函数是类别中从一个对象到另一个对象的态射.

同样Functor我们有:

  • 一个Type构造函数,用于将对象从一个类别映射到另一个类别
  • fmap 用于将态射从一个类别映射到另一个类别.

现在,当我们编写程序时,我们基本上会转换值(而不是类型),似乎Hask的类别根本不讨论值.我试图在整个等式中拟合值,并得出以下观察结果:

  • 每个类型本身就是一个类别.例如:Int是所有整数的类别.
  • 从值到相同类型的另一个值的函数是类别的态射.例如:Int -> Int
  • 从一个值到另一个不同类型的值的函数是用于将一种类型的值映射到另一种类型的函数.

现在我的问题是 - 在Hask类别(或一般类别理论)中,值是否有意义?如果是,那么任何关于它的参考或如果没有,那么任何原因.

我希望这个问题有道理:)

haskell category-theory

24
推荐指数
4
解决办法
1961
查看次数

将列表分组为Haskell中的n个元素的列表

库中的列表上是否有一个操作来生成n个元素的组?例如:n = 3

groupInto 3 [1,2,3,4,5,6,7,8,9] = [[1,2,3],[4,5,6],[7,8,9]]
Run Code Online (Sandbox Code Playgroud)

如果没有,我该怎么办?

haskell list

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

为什么Haskell中的因子计算要比Java中快得多

我遇到的一个编程问题涉及计算大数(最多10 ^ 5的数字)的阶乘.我见过一个简单的Haskell代码,就像这样

factorial :: (Eq x, Num x) => x -> x
factorial 0 = 1
factorial a = a * factorial (a - 1)
Run Code Online (Sandbox Code Playgroud)

即使没有代码中涉及的任何缓存,它也会隐式处理大量数字并以某种方式运行得更快.

当我尝试使用Java解决问题时,我不得不使用BigInteger来保存大数字并使用因子的迭代版本

public static BigInteger factorialIterative(int n)
{
        if(n == 0 || n == 1) return BigInteger.valueOf(1);
        BigInteger f = BigInteger.valueOf(1);
        for(int i = 1 ; i <= n ;i++)
            f = f.multiply(BigInteger.valueOf(i));
        return f;
}
Run Code Online (Sandbox Code Playgroud)

上述代码超出了程序执行的设定时间限制.我也尝试了factorial的缓存递归版本

public static BigInteger factorial(int n)
{
     if(cache[n] != null) 
         return cache[n];
     else if(n == 0) 
         return new …
Run Code Online (Sandbox Code Playgroud)

java haskell factorial

21
推荐指数
3
解决办法
4433
查看次数

是否可以使用包围语法糖作为应用函子?

McBride和Paterson的"有效的应用程序设计"中,他们介绍了一些可爱的语法糖来提升纯粹的功能:

[| f x y z |]
Run Code Online (Sandbox Code Playgroud)

对于

f <$> x <*> y <*> z
Run Code Online (Sandbox Code Playgroud)

我记得别人的地方使用li f w x y z ilil f v w x y z li,我想/希望,也许是因为它可以使用一些现有的语言功能和狡猾的定义来定义liil.

我无法找到超越纸本的任何参考,并假设[||]不太可能在GHC任何时间很快转起来,是有可能实现liil不知何故?我不能为他们想出一个合理的类型,所以我假设我需要模板Haskell或类似,但不知道几乎足以实现这一点.[af| f x y ]没关系,但我不知道在我开始尝试它之前是否可能,如果确实需要帮助.

haskell syntactic-sugar applicative template-haskell

20
推荐指数
3
解决办法
914
查看次数

Haskell树分裂:有人可以解释一下这行吗?

split s (Root x lst rst)
 | s < x = let (nlt, nrt) = split s lst in
     (nlt, Root x nrt rst)
Run Code Online (Sandbox Code Playgroud)

有人可以解释这一行吗?我真的没有得到这个let部分.

我试着想一想,我不知道我是否做对了:我们绑定(nlt, nrt),结果split s lst; 而且split s lst本身就是(nlt, Root x nrt rst)

是吗?

这是完整的代码:

split :: Ord a => a -> Tree a -> (Tree a, Tree a)
split _ Empty = (Empty, Empty)
split s (Root x lst rst)
 | s < x = let (nlt, …
Run Code Online (Sandbox Code Playgroud)

haskell

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

数字作为乘法函数(奇怪但有趣)

Haskell中隐性函数组合问题的评论中,人们提到制作一个Num实例a -> r,所以我想我会使用函数表示法来表示乘法:

{-# LANGUAGE TypeFamilies #-}
import Control.Applicative

instance Show (a->r) where   -- not needed in recent GHC versions
  show f = " a function "

instance Eq (a->r) where     -- not needed in recent GHC versions
  f == g = error "sorry, Haskell, I lied, I can't really compare functions for equality"

instance (Num r,a~r) => Num (a -> r) where
  (+) = liftA2 (+)
  (-) = liftA2 (-)
  (*) = …
Run Code Online (Sandbox Code Playgroud)

haskell

17
推荐指数
1
解决办法
624
查看次数

为类型为* - >*的类型类的实例键入参数约束

假设我有Heap a类型Heap的类型构造函数* -> *.堆上的许多基本操作都要求a类型是Ord类类的实例.

data Heap a = ...

findMin :: Ord a => Heap a -> a
deleteMin :: Ord a => Heap a -> Heap a
Run Code Online (Sandbox Code Playgroud)

我想将Heap类型声明为Foldable类型类的实例,只要a类型参数是Ord类型类的实例(它将很容易表达通过findMindeleteMin函数).

当我们处理需要类型的类型类时,可以很容易地表达这种关系*,例如Show:

instance Show a => Show (Heap a) where
    show h = ...
Run Code Online (Sandbox Code Playgroud)

但是我在申报时遇到了问题Foldable:

instance Foldable Heap where
    -- Ouch, there is no …
Run Code Online (Sandbox Code Playgroud)

haskell typeclass

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

为什么折叠离开期望(a - > b - > a)而不是(b - > a - > a)?

我想知道为什么fold左边的函数有类型签名a -> b -> a而不是b -> a -> a.这背后有设计决定吗?

例如,在Haskell中,我必须编写foldl (\xs x -> x:xs) [] xs反转列表而不是更短的foldl (:) [] xs(这可能是b -> a -> a).另一方面,存在需要标准的用例a -> b -> a.在Scala中,这可能是附加的:xs.foldLeft(List.empty[Int]) ((xs, x) => xs:+x)可以写成xs.foldLeft(List.empty[Int]) (_:+_).

是否会出现需要给定类型签名而不是替代签名的更多用例,或者是否有其他决策导致在Haskell和Scala(可能还有许多其他语言)中折叠左侧的设计?

haskell functional-programming scala

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