我对F#很陌生,发现类型推断确实很酷.但目前似乎它也可能导致代码重复,这不是一件很酷的事情.我想总结一个这样的数字的数字:
let rec crossfoot n =
if n = 0 then 0
else n % 10 + crossfoot (n / 10)
crossfoot 123
Run Code Online (Sandbox Code Playgroud)
这正确打印6.但是现在我的输入数字不适合32位,所以我必须将其转换为.
let rec crossfoot n =
if n = 0L then 0L
else n % 10L + crossfoot (n / 10L)
crossfoot 123L
Run Code Online (Sandbox Code Playgroud)
然后,BigInteger我来了,猜猜是什么......
当然,我只能提供bigint版本和转换输入参数,并根据需要输出参数.但首先我假设使用BigInteger过度int有一些性能惩罚.第二个let cf = int (crossfoot (bigint 123))不好看.
写这个没有通用的方法吗?
对于工作中的参数优化问题,我写了一个遗传算法来找到一些好的设置,因为蛮力解决方案是不可行的.不幸的是,当我早上回来时,大部分时间我都会被送到StackOverflowException.
我已经使用F#已经有一段时间了所以我知道TCO和需要带累加器参数的函数,并且通常使用该形式.
经过大量的搜索,我认为我能够找到触发异常的代码:
breedPopulation alive |> simulate (generation + 1) lastTime ewma
Run Code Online (Sandbox Code Playgroud)
breedPopulation从当前个体中生成新一代alive.然后通过调用开始下一轮/生成simulate.当我看到反汇编(总noob)时,我发现了一些pop和a ret,所以它看起来不像是对我的常规(非尾部)调用.
mov rcx,qword ptr [rbp+10h]
mov rcx,qword ptr [rcx+8]
mov rdx,qword ptr [rbp-40h]
cmp dword ptr [rcx],ecx
call 00007FFA3E4905C0
mov qword ptr [rbp-0F0h],rax
mov r8,qword ptr [rbp-0F0h]
mov qword ptr [rbp-80h],r8
mov r8,qword ptr [rbp-78h]
mov qword ptr [rsp+20h],r8
mov r8d,dword ptr [rbp+18h]
inc r8d
mov rdx,qword ptr [rbp+10h]
mov r9,qword ptr [rbp-20h]
mov rcx,7FFA3E525960h
call 00007FFA3E4A5040 …Run Code Online (Sandbox Code Playgroud) 通常在F#中编写通用代码时,我会遇到与此类似的情况(我知道这非常低效,仅用于演示目的):
let isPrime n =
let sq = n |> float |> sqrt |> int
{2..sq} |> Seq.forall (fun d -> n % d <> 0)
Run Code Online (Sandbox Code Playgroud)
对于许多问题,我可以使用静态解析的类型,并通过内联获得性能提升.
let inline isPrime (n:^a) =
let two = LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne
let sq = n |> float |> sqrt |> int
{two..sq} |> Seq.forall (fun d -> n % d <> LanguagePrimitives.GenericZero)
Run Code Online (Sandbox Code Playgroud)
由于上限序列是一个浮点数,上面的代码将无法编译.非理性地说,我可以退回到int例如.
但是编译器不允许我使用以下任何一个:
let sq = n |> float |> sqrt :> ^alet sq = …我想绑定到ObservableCollectionXAML中,并在那里应用分组.原则上,这很好.
<UserControl.Resources>
<CollectionViewSource x:Key="cvs" Source="{Binding Path=TestTemplates}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Title"/>
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="TestCategory"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
然后数据绑定表达式ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}"代替ItemsSource="{Binding Path=TestTemplates}".
起初,一切看起来都很酷,直到我想从视图模型中刷新UI.问题是,CollectionViewSource.GetDefaultView(TestTemplates)返回的视图与应用分组的XAML中的视图不同.因此,我无法设置选择或做任何有用的事情.
我可以通过将列表再次直接绑定到视图模型的属性并在代码隐藏中设置分组来修复它.但我对这个解决方案并不满意.
private void UserControlLoaded(object sender, RoutedEventArgs e)
{
IEnumerable source = TemplateList.ItemsSource;
var cvs = (CollectionView)CollectionViewSource.GetDefaultView(source);
if (cvs != null)
{
cvs.SortDescriptions.Add(new SortDescription("Title", ListSortDirection.Ascending));
cvs.GroupDescriptions.Add(new PropertyGroupDescription("TestCategory"));
}
}
Run Code Online (Sandbox Code Playgroud)
我认为,其原因已由John Skeet在此提供.
尽管如此,我希望应该有一种方法来获得正确的观点.我错了吗?
我想用2-3个手指树来玩,如Hinze的(Haskell)论文所述(另见本博客).
type Node<'a> =
| Node2 of 'a * 'a
| Node3 of 'a * 'a * 'a
static member OfList = function
| [a; b] -> Node2(a, b)
| [a; b; c] -> Node3(a, b, c)
| _ -> failwith "Only lists of length 2 or 3 accepted!"
member me.ToList () =
match me with
| Node2(a, b) -> [a; b]
| Node3(a, b, c) -> [a; b; c]
type Digit<'a> =
| One of …Run Code Online (Sandbox Code Playgroud) 我有这个 lambda 风格的函数调用
foldr((l,r) -> r+1, "12345"; init=0)
Run Code Online (Sandbox Code Playgroud)
Julia 很高兴地将其计算为 5。将其重写为do如下所示的样式
foldr("12345"; init=0) do (l,r) # I also tried ((l,r),) and just tup
# l,r = tup # and then destructure here
r+1
end
Run Code Online (Sandbox Code Playgroud)
据我了解,这两者应该是等价的。不幸的是,Julia 1.7.0-rc3 不同意我的观点:
错误:MethodError:没有方法匹配 (::var"#36#37")(::Char, ::Int64)
最接近的候选者是:(
::var"#36#37")(::Any) at REPL[ 25]:2
Stacktrace:
[1] FlipArgs
@ ./reduce.jl:196 [内联]
[2] BottomRF
@ ./reduce.jl:81 [内联]
[3] _foldl_impl(op::Base.BottomRF{Base. FlipArgs{var"#36#37"}}, init::Int64, itr::Base.Iterators.Reverse{String})
@ Base ./reduce.jl:58
[4] Foldl_impl(op::Base.BottomRF{ Base.FlipArgs{var"#36#37"}}, nt::Int64, itr::Base.Iterators.Reverse{String})
@ Base ./reduce.jl:48
[5] mapfoldr_impl(f::Function, op::Function、nt::Int64、itr::String)
@ Base ./reduce.jl:186 …
我想在学习 Raku 的同时对 Python 和 Raku 进行一些比较。
\n本来我想要一个更大的脚本,但由于差异已经很大,我现在就寻求指导。
\n我尝试忠实地翻译这个 Python 脚本,同时应用不应该损害性能的 Raku 知识:
\nfrom collections import deque\nfrom itertools import count, islice\n\n\ndef primes_wheel():\n yield 2\n composites = {}\n for candidate in count(3, step=2):\n prime = composites.pop(candidate, 0)\n if prime:\n while True:\n candidate += prime + prime\n if candidate not in composites:\n composites[candidate] = prime\n break\n else:\n composites[candidate * candidate] = candidate\n yield candidate\n\n\ndef last(itr):\n return deque(itr, 1).pop()\n\n\nLENGTH = 99999\n\nprint(last(islice(primes_wheel(), 0, LENGTH)))\nRun Code Online (Sandbox Code Playgroud)\n我到达了这个:
\nsub primes_wheel {\n my …Run Code Online (Sandbox Code Playgroud) 源于这个问题,我有这个小F#代码(github)根据正态分布生成随机值:
// val nextSingle : (unit -> float32)
let nextSingle =
let r = System.Random()
r.NextDouble >> float32
// val gauss : (float32 -> float32 -> seq<float32>)
let gauss mean stdDev =
let rec gauss ready = seq {
match ready with
| Some spare ->
yield spare * stdDev + mean
yield! gauss None
| _ ->
let rec loop () =
let u = nextSingle() * 2.f - 1.f
let v = nextSingle() * …Run Code Online (Sandbox Code Playgroud) 我对 Julia 很陌生,但我对 Scheme/Rust/F# 有一定的了解。
今天我想让昨天的 AoC更好,而不需要明确数量的嵌套循环。
我找到了这个可行的解决方案,但我不喜欢最后一个if. 在上面提到的语言中,我会调用一个函数(或使用计算表达式),它给我的第一个结果不是None. 对于朱莉娅,我期望的东西做的。它确实如此,但出乎意料地以一种热切的方式出现。
所以当我尝试时return something(find(r, n, start + 1, which), find(r, n - 1, start + 1, extended)),当第一个参数已经有结果时,它也会评估第二个参数 - 因此崩溃。
是否有宏/懒惰版本或something我没有找到?遇到这样的案子该怎么办?
我也想过(短路)或将它们放在一起,但我猜朱莉娅在这件事上的严格破坏了这一点。
using DataStructures
function find(r::Array{Int}, n, start = 1, which = nil())::Union{Int,Nothing}
if start <= length(r)
extended = cons(start, which)
with_current = sum(i -> r[i], extended)
if with_current == 2020 && n == 1
return prod(i -> r[i], …Run Code Online (Sandbox Code Playgroud) 我读了这篇关于这个算法的F#版本的帖子.我发现它非常优雅,并试图结合一些答案的想法.
虽然我对它进行了优化以减少检查(仅检查6左右的数字)并省去不必要的缓存,但仍然很慢.计算10,000 次素数已经超过5分钟.使用命令式方法,我可以在更长的时间内测试所有31位整数.
所以我的问题是,如果我遗漏了使这一切变得如此缓慢的事情.例如,在另一篇文章中有人猜测LazyList可能会使用锁定.有没有人有想法?
由于StackOverflow的规则说不要将新问题作为答案发布,我觉得我必须为此开始一个新主题.
这是代码:
#r "FSharp.PowerPack.dll"
open Microsoft.FSharp.Collections
let squareLimit = System.Int32.MaxValue |> float32 |> sqrt |> int
let around6 = LazyList.unfold (fun (candidate, (plus, next)) ->
if candidate > System.Int32.MaxValue - plus then
None
else
Some(candidate, (candidate + plus, (next, plus)))
) (5, (2, 4))
let (|SeqCons|SeqNil|) s =
if Seq.isEmpty s then SeqNil
else SeqCons(Seq.head s, Seq.skip 1 s)
let rec lazyDifference l1 l2 =
if Seq.isEmpty l2 then …Run Code Online (Sandbox Code Playgroud)