Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
]
},
"paket": {
"version": "7.1.5",
"version": "8.0.3",
"commands": [
"paket"
]
Expand All @@ -33,4 +33,4 @@
]
}
}
}
}
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
dotnet: [6.0.401]
dotnet: [8.0.416]
node: ['14']
runs-on: ${{ matrix.os }}

Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.401",
"version": "8.0.416",
"rollForward": "minor"
}
}
}
2 changes: 1 addition & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
framework: netstandard2.0, net6.0
framework: netstandard2.0, net8.0
source https://api.nuget.org/v3/index.json

nuget FSharp.Core >= 4.3.4 lowest_matching:true
Expand Down
10 changes: 10 additions & 0 deletions src/FSharpx.Collections/Collections.fs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ module Seq =
let splitAt n seq =
(Seq.take n seq, Seq.skip n seq)

/// The same as Seq.skip except will return None if not enough elements to skip or count passed is < 1
[<TailCall>]
let rec trySkip<'T> (count: int) (source: seq<'T>) : Option<seq<'T>> =
if count < 1 then
None
else
match tryHeadTail source with
| None -> None
| Some(head, tail) -> if count = 1 then Some tail else trySkip (count - 1) tail

/// Splits a sequences up to the point where the predicate holds
let span predicate source =
(Seq.takeWhile predicate source, Seq.skipWhile predicate source)
Expand Down
32 changes: 30 additions & 2 deletions tests/FSharpx.Collections.Tests/SeqTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,32 @@ module SeqTests =
| _ -> failwith "Unreachable"
}

test "If I trySkip and I don't have a head, I should return None" { Seq.empty<float> |> Seq.trySkip 1 |> Expect.isNone "trySkip1" }

test "If I trySkip1 a non-empty seq, I should return just tail" {
let data = [ 1; 2; 3 ]
let actual = data |> Seq.trySkip 1
Expect.isSome "trySkip1" actual

match actual with
| Some subSeq -> Expect.sequenceEqual "trySkip1" [ 2; 3 ] subSeq
| _ -> failwith "Unreachable"
}

test "If I trySkip2 a non-empty seq, I should return just last" {
let data = [ 1; 2; 3 ]
let actual = data |> Seq.trySkip 2
Expect.isSome "trySkip2" actual

match actual with
| Some subSeq -> Expect.sequenceEqual "trySkip2" [ 3 ] subSeq
| _ -> failwith "Unreachable"
}

test "If I trySkip2 and seq only contains 1 element, I should return None" {
seq { yield 1 } |> Seq.trySkip 2 |> Expect.isNone "trySkip2"
}

test "I should be a to split a seq at an index" {
let (a, b) = Seq.splitAt 5 data
Expect.sequenceEqual "splitAt" (List.toSeq [ 1.; 2.; 3.; 4.; 5. ]) a
Expand Down Expand Up @@ -138,9 +164,11 @@ module SeqTests =

test "I should get some if try to get a index inside the seq" { Seq.tryNth 2 data |> Expect.equal "tryNth" (Some(3.)) }

test "I should get none when trySkip past the end of the seq" { Seq.skipNoFail 20 data |> Expect.sequenceEqual "skipNoFail" Seq.empty }
test "I should get empty seq when skipNoFail past the end of the seq" {
Seq.skipNoFail 20 data |> Expect.sequenceEqual "skipNoFail" Seq.empty
}

test "I should get Some when trySkip" {
test "I should get Some when skipNoFail" {
Seq.skipNoFail 5 data
|> Expect.sequenceEqual "skipNoFail" (List.toSeq [ 6.; 7.; 8.; 9.; 10. ])
}
Expand Down
Loading