我今天在unix中发现了"time"命令,并认为我会用它来检查Haskell中尾递归和正常递归函数之间运行时的差异.
我写了以下函数:
--tail recursive
fac :: (Integral a) => a -> a
fac x = fac' x 1 where
fac' 1 y = y
fac' x y = fac' (x-1) (x*y)
--normal recursive
facSlow :: (Integral a) => a -> a
facSlow 1 = 1
facSlow x = x * facSlow (x-1)
Run Code Online (Sandbox Code Playgroud)
这些都是有效的,记住它们只是用于这个项目,所以我没有费心去检查零或负数.
但是,在为每个编写一个main方法,编译它们,并使用"time"命令运行它们时,两者都具有相似的运行时,正常的递归函数使尾递归函数边缘化.这与我在lisp中关于尾递归优化的内容相反.这是什么原因?
optimization haskell tail-recursion lazy-evaluation tail-call-optimization
我正在学习Haskell,并且遇到了以下代码:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)
就其工作方式而言,我在解析方面遇到了一些麻烦.它非常整洁,我知道不需要更多内容,但我想了解Haskell在写作时如何设法"填写"文件:
take 50 fibs
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
谢谢!
我试图找到一个对DataKinds扩展的解释,这对我来说只是读过Learn You a Haskell才有意义.是否有一个标准的来源,对我来说,我学到的东西很少?
编辑:例如文档说
使用-XDataKinds,GHC会自动将每个合适的数据类型提升为一种类型,并将其(值)构造函数作为类型构造函数.以下类型
并举例说明
data Nat = Ze | Su Nat
Run Code Online (Sandbox Code Playgroud)
产生以下种类和类型构造函数:
Nat :: BOX
Ze :: Nat
Su :: Nat -> Nat
Run Code Online (Sandbox Code Playgroud)
我没有明白这一点.虽然我不明白是什么BOX
意思,陈述Ze :: Nat
和Su :: Nat -> Nat
似乎说明的是,通常已经是泽和苏都是正常的数据构造完全一样,你希望看到与ghci的情况
Prelude> :t Su
Su :: Nat -> Nat
Run Code Online (Sandbox Code Playgroud) 我看不到语言的评估策略与其纯度之间的联系。考虑到推文作者的声誉,我肯定忽略了一些东西。也许有人可以阐明一些观点。
haskell functional-programming language-implementation lazy-evaluation purity
只有素数因子为2,3或5的数字称为丑陋数字.
例:
1,2,3,4,5,6,8,9,10,12,15 ......
1可以被认为是2 ^ 0.
我正在努力寻找第n个难看的数字.请注意,当n变大时,这些数字非常稀疏地分布.
我写了一个简单的程序来计算给定数字是否丑陋.对于n> 500 - 它变得超级慢.我尝试使用memoization - 观察:ugly_number*2,ugly_number*3,ugly_number*5都很难看.即便如此,它也很慢.我尝试使用log的一些属性 - 因为这会将这个问题从乘法减少到另外 - 但是,运气不大.想与大家分享这个.任何有趣的想法?
使用类似于"Eratosthenes的筛子"的概念(感谢Anon)
for (int i(2), uglyCount(0); ; i++) {
if (i % 2 == 0)
continue;
if (i % 3 == 0)
continue;
if (i % 5 == 0)
continue;
uglyCount++;
if (uglyCount == n - 1)
break;
}
Run Code Online (Sandbox Code Playgroud)
我是第n个难看的数字.
即便这样也很慢.我想找到第1500个难看的数字.
我想问一下这是否是检查数字是否为素数的正确方法?因为我读到0和1不是素数.
int num1;
Console.WriteLine("Accept number:");
num1 = Convert.ToInt32(Console.ReadLine());
if (num1 == 0 || num1 == 1)
{
Console.WriteLine(num1 + " is not prime number");
Console.ReadLine();
}
else
{
for (int a = 2; a <= num1 / 2; a++)
{
if (num1 % a == 0)
{
Console.WriteLine(num1 + " is not prime number");
return;
}
}
Console.WriteLine(num1 + " is a prime number");
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud) 制作一个简单的筛子很容易:
for (int i=2; i<=N; i++){
if (sieve[i]==0){
cout << i << " is prime" << endl;
for (int j = i; j<=N; j+=i){
sieve[j]=1;
}
}
cout << i << " has " << sieve[i] << " distinct prime factors\n";
}
Run Code Online (Sandbox Code Playgroud)
但是当N非常大并且我无法在内存中保存那种数组时呢?我已经查找了分段筛选方法,它们似乎涉及到找到素数直到sqrt(N),但我不明白它是如何工作的.如果N非常大(例如10 ^ 18)怎么办?
algorithm primes sieve-of-eratosthenes prime-factoring factors
我正在研究Data.List模块中的代码,并不能完全围绕这种排列实现:
permutations :: [a] -> [[a]]
permutations xs0 = xs0 : perms xs0 []
where
perms [] _ = []
perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is)
where interleave xs r = let (_,zs) = interleave' id xs r in zs
interleave' _ [] r = (ts, r)
interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r
in (y:us, f (t:y:us) : zs)
Run Code Online (Sandbox Code Playgroud)
有人可以详细解释这些嵌套函数如何相互连接/相互作用?
我发现在Python或Common Lisp中你可以在运行时列出库的内容.Haskell有同样的事情,尤其是GHCI提示吗?
我对纯粹功能性F#中的eratosthenes筛子的实施很感兴趣.我对实际筛子的实现感兴趣,而不是真正的筛子的天真功能实现,所以不是这样的:
let rec PseudoSieve list =
match list with
| hd::tl -> hd :: (PseudoSieve <| List.filter (fun x -> x % hd <> 0) tl)
| [] -> []
Run Code Online (Sandbox Code Playgroud)
上面的第二个链接简要描述了一个需要使用多图的算法,据我所知,这在F#中是不可用的.给出的Haskell实现使用了一个支持insertWith
方法的映射,我在F#功能映射中没有看到它.
有没有人知道将给定的Haskell映射代码转换为F#的方法,或者可能知道替代实现方法或筛选算法哪些有效且更适合功能实现或F#?
haskell ×6
algorithm ×3
primes ×3
factors ×2
list ×2
c# ×1
data-kinds ×1
f# ×1
fibonacci ×1
math ×1
optimization ×1
permutation ×1
purity ×1
types ×1