我想测试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获胜的明显案例吗?
module StackOverflow where -- yes, the source of this post compiles as is
Run Code Online (Sandbox Code Playgroud)
如果您想先玩这个(1/2向下),请跳到下面的操作以使其正常工作.如果我稍微
停下来,你会跳到我想要的东西,你只想找到我正在寻求的帮助.
:so我在我定义的命令中ghci.conf吗? :l可以用于.hs和.lhs像往常一样的文件,但使用我的手写预处理器的.so文件?Haskell支持.lhs源文件中的文字编程,有两种方式:
\begin{code}和\end{code}.>,其他任何东西都是评论.>).Bird不跟踪类似于StackOverflow代码块的规则声音吗?
参考文献: 1. 将.ghci手册
2. GHCI haskellwiki
3. 关于尼尔·米切尔的博客:{,并:}在.ghci
我喜欢在文本编辑器中编写SO答案,我喜欢发表一个包含有效代码的帖子,但最后还是>在发布之前我必须编辑的注释块或者s,这不那么有趣.
所以,我自己写了一个预处理器.
*或开头:. …所以我们有Hask类别,其中:
同样Functor我们有:
fmap 用于将态射从一个类别映射到另一个类别.现在,当我们编写程序时,我们基本上会转换值(而不是类型),似乎Hask的类别根本不讨论值.我试图在整个等式中拟合值,并得出以下观察结果:
Int -> Int现在我的问题是 - 在Hask类别(或一般类别理论)中,值是否有意义?如果是,那么任何关于它的参考或如果没有,那么任何原因.
我希望这个问题有道理:)
库中的列表上是否有一个操作来生成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)
如果没有,我该怎么办?
我遇到的一个编程问题涉及计算大数(最多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) 在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 il或il f v w x y z li,我想/希望,也许是因为它可以使用一些现有的语言功能和狡猾的定义来定义li和il.
我无法找到超越纸本的任何参考,并假设[|并|]不太可能在GHC任何时间很快转起来,是有可能实现li并il不知何故?我不能为他们想出一个合理的类型,所以我假设我需要模板Haskell或类似,但不知道几乎足以实现这一点.[af| f x y ]没关系,但我不知道在我开始尝试它之前是否可能,如果确实需要帮助.
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中隐性函数组合问题的评论中,人们提到制作一个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) 假设我有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类型类的实例(它将很容易表达通过findMin和deleteMin函数).
当我们处理需要类型的类型类时,可以很容易地表达这种关系*,例如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) 我想知道为什么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 ×10
applicative ×1
combinators ×1
factorial ×1
fold ×1
ghci ×1
java ×1
list ×1
optimization ×1
scala ×1
typeclass ×1