Created
November 3, 2016 04:01
-
-
Save TeaDrivenDev/701e6afb46dee837d4287d57a8d8c8a7 to your computer and use it in GitHub Desktop.
F# functions I use a lot, mostly in prototyping; functionally correct, not necessarily efficient.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
let asFst second first = first, second | |
let asSnd first second = first, second | |
let swap (a, b) = b, a | |
type FullJoinResult<'TLeft, 'TRight> = | |
| LeftOnly of 'TLeft | |
| RightOnly of 'TRight | |
| JoinMatch of 'TLeft * 'TRight | |
let private ofObj (o : 'T) = | |
match box o with | |
| null -> None | |
| value -> Some (value :?> 'T) | |
module Option = | |
let orValue alternativeValue opt = defaultArg opt alternativeValue | |
let toNullable opt = | |
match opt with | |
| Some value -> Nullable value | |
| None -> Nullable() | |
module Seq = | |
open System.Linq | |
open System.Collections | |
let ofType<'T> (sequence : IEnumerable) = sequence.OfType<'T>() | |
let groupByFst sequence = | |
sequence |> Seq.groupBy fst |> Seq.map (fun (first, tuples) -> first, tuples |> Seq.map snd) | |
let join innerKeySelector outerKeySelector (inner : 'TInner seq) (outer : 'TOuter seq) = | |
query { | |
for o in outer do | |
join i in inner on | |
(outerKeySelector o = innerKeySelector i) | |
select (o, i) | |
} | |
let leftJoin innerKeySelector outerKeySelector (inner : seq<'TInner>) (outer : seq<'TOuter>) = | |
query { | |
for o in outer do | |
leftOuterJoin i in inner on | |
(outerKeySelector o = innerKeySelector i) into result | |
for joined in result.DefaultIfEmpty() do | |
select (o, joined |> ofObj) | |
} | |
let fullOuterJoin innerKeySelector outerKeySelector (right : 'TRight seq) (left : 'TLeft seq) = | |
let optionizeFirst (a, b) = Some a, b | |
let valueInOuter = | |
leftJoin innerKeySelector outerKeySelector right left | |
|> Seq.map optionizeFirst | |
let valueInInnerOnly = | |
leftJoin outerKeySelector innerKeySelector left right | |
|> Seq.filter (snd >> Option.isNone) | |
|> Seq.map (optionizeFirst >> swap) | |
Seq.append valueInOuter valueInInnerOnly | |
|> Seq.map (function | |
| Some leftItem, Some rightItem -> JoinMatch (leftItem, rightItem) | |
| Some leftItem, None -> LeftOnly leftItem | |
| None, Some rightItem -> RightOnly rightItem | |
| None, None -> failwith "This can never happen.") | |
let groupJoin innerKeySelector outerKeySelector (inner : 'TInner seq) (outer : 'TOuter seq) = | |
outer | |
.GroupJoin(inner, | |
Func<_, 'TKey> outerKeySelector, | |
Func<_, _> innerKeySelector, | |
Func<_, _, _> (fun outer innerGroup -> outer, innerGroup)) :> _ seq | |
let toLookup (keySelector : 'TSource -> 'TLookup) (sequence : 'TSource seq) = | |
sequence.ToLookup(Func<_, _> keySelector) | |
let toLookupWithSelector (keySelector : 'TSource -> 'TLookup) (elementSelector : 'TSource -> 'TElement) (sequence : 'TSource seq) = | |
sequence.ToLookup(Func<_, _> keySelector, Func<_, _> elementSelector) | |
module Dictionary = | |
open System.Collections.Generic | |
let tryGetValue key (dictionary : IDictionary<'TKey, 'TValue>) = | |
match dictionary.TryGetValue key with | |
| true, value -> Some value | |
| false, _ -> None | |
module String = | |
let split separator (s : string) = s.Split separator | |
let trim (s : string) = s.Trim() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment