相关疑难解决方法(0)

了解F#值限制错误

我不明白F#中的价值限制是如何运作的.我已经阅读了wiki中的解释以及MSDN文档.我不明白的是:

  1. 例如,为什么这给了我一个价值限制错误(取自这个问题):

    let toleq (e:float<_>) a b = (abs ( a - b ) ) < e
    
    Run Code Online (Sandbox Code Playgroud)

    但这不是:

    let toleq e (a:float<_>) b = (abs ( a - b ) ) < e
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这一点可以概括......

    let is_bigger a b = a < b
    
    Run Code Online (Sandbox Code Playgroud)

    但这不是(它被指定为int):

    let add a b = a + b
    
    Run Code Online (Sandbox Code Playgroud)
  3. 为什么带隐式参数的函数会生成值限制:

    这个:

    let item_count = List.fold (fun acc _ -> 1 + acc) 0
    
    Run Code Online (Sandbox Code Playgroud)

    对此:

    let item_count l = List.fold (fun acc _ …
    Run Code Online (Sandbox Code Playgroud)

f# type-inference value-restriction

20
推荐指数
2
解决办法
3582
查看次数

最常用的方法是在F#中编写批量大小的seq

我正在尝试通过将一些C#算法重写为惯用的F#来学习F#.

我正在尝试重写的第一个函数之一是batchesOf,其中:

[1..17] |> batchesOf 5
Run Code Online (Sandbox Code Playgroud)

哪个会将序列分成多个批次,每个最多五个,即:

[[1; 2; 3; 4; 5]; [6; 7; 8; 9; 10]; [11; 12; 13; 14; 15]; [16; 17]]
Run Code Online (Sandbox Code Playgroud)

我第一次尝试这样做有点丑陋,我在尝试在闭包内部使用可变类型时遇到错误而使用了一个可变的ref对象.使用ref特别不愉快,因为要取消引用它你必须使用!在一个条件表达式内部的操作符可以与某些开发人员相反直观,这些开发人员将其视为逻辑不符合.我遇到的另一个问题是Seq.skip和Seq.take与他们的Linq别名不同,如果大小超过序列的大小,他们将抛出错误.

let batchesOf size (sequence: _ seq) : _ list seq =
    seq {
        let s = ref sequence
        while not (!s |> Seq.isEmpty)  do
            yield !s |> Seq.truncate size |> List.ofSeq
            s := System.Linq.Enumerable.Skip(!s, size)
    }
Run Code Online (Sandbox Code Playgroud)

无论如何,在F#中重写这个最优雅/惯用的方法是什么?保持原始行为但最好没有ref可变变量.

linq f# functional-programming sequence

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

F#:我如何将序列分成序列序列

背景:

我有一系列连续的,带时间戳的数据.数据序列中存在间隙,其中数据不连续.我想创建一种方法将序列分成序列序列,以便每个子序列包含连续数据(在间隙处分割输入序列).

约束:

  • 返回值必须是序列序列,以确保元素仅在需要时生成(不能使用列表/数组/缓存)
  • 解决方案不能是O(n ^ 2),可能排除Seq.take - Seq.skip模式(参见Brian的帖子)
  • 功能惯用方法的奖励点(因为我希望在功能编程方面更加精通),但这不是必需的.

方法签名

let groupContiguousDataPoints (timeBetweenContiguousDataPoints : TimeSpan) (dataPointsWithHoles : seq<DateTime * float>) : (seq<seq< DateTime * float >>)= ... 
Run Code Online (Sandbox Code Playgroud)

从表面上看,问题看起来微不足道,但即使采用Seq.pairwise,IEnumerator <_>,序列理解和屈服声明,解决方案也让我望而却步.我确信这是因为我仍然缺乏组合F#-idioms的经验,或者可能是因为我还没有接触过一些语言结构.

// Test data
let numbers = {1.0..1000.0}
let baseTime = DateTime.Now
let contiguousTimeStamps = seq { for n in numbers ->baseTime.AddMinutes(n)}

let dataWithOccationalHoles = Seq.zip contiguousTimeStamps numbers |> Seq.filter (fun (dateTime, num) -> num % 77.0 <> 0.0) // Has a gap in the data every …
Run Code Online (Sandbox Code Playgroud)

f# sequences

10
推荐指数
1
解决办法
2889
查看次数

在F#中拆分seq

我应该分割seq<a>seq<seq<a>>由所述元件的一个属性.如果此属性等于给定值,则必须在该点处"拆分".我怎么能在FSharp中做到这一点

如果必须在该项目中进行拆分,则将"函数"传递给它并返回bool应该是不错的.

示例:输入序列:seq: {1,2,3,4,1,5,6,7,1,9} 当它等于1时,应在每个项目上进行拆分,因此结果应为:

seq
{
seq{1,2,3,4}
seq{1,5,6,7}
seq{1,9}
}
Run Code Online (Sandbox Code Playgroud)

f# split seq

8
推荐指数
1
解决办法
2219
查看次数

基于谓词将列表拆分为列表列表

(我知道这个问题,但它与序列有关,这不是我的问题)

鉴于此输入(例如):

let testlist = 
    [  
       "*text1";
       "*text2";
       "text3";
       "text4";
       "*text5";
       "*text6";
       "*text7"
    ]

let pred (s:string) = s.StartsWith("*")
Run Code Online (Sandbox Code Playgroud)

我希望能够调用MyFunc pred testlist并获得此输出:

[
    ["*text1";"*text2"];
    ["*text5";"*text6";"*text7"]
]
Run Code Online (Sandbox Code Playgroud)

这是我目前的解决方案,但我真的不喜欢嵌套的List.revs(忽略它需要Seq作为输入的事实)

let shunt pred sq =
    let shunter (prevpick, acc) (pick, a) = 
        match pick, prevpick with
        | (true, true)  -> (true, (a :: (List.hd acc)) :: (List.tl acc))
        | (false, _)    -> (false, acc)
        | (true, _)     -> (true, [a] :: acc)

    sq 
        |> Seq.map (fun a -> (pred …
Run Code Online (Sandbox Code Playgroud)

f#

3
推荐指数
2
解决办法
2308
查看次数