Skip to content

Instantly share code, notes, and snippets.

@TeaDrivenDev
Created November 3, 2016 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TeaDrivenDev/701e6afb46dee837d4287d57a8d8c8a7 to your computer and use it in GitHub Desktop.
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.
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