Advertisement
Guest User

Untitled

a guest
Aug 18th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.88 KB | None | 0 0
  1. open System.Threading.Tasks
  2. open FSharp.Control.Tasks.V2
  3.  
  4. [<RequireQualifiedAccess>]
  5. [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  6. module Lazy =
  7. let map (fn : 'T -> 'U) (x : Lazy<'T>) =
  8. Lazy.Create(fun () -> fn x.Value)
  9.  
  10. [<Struct>]
  11. type Immediate<'T> =
  12. | Success of value : 'T
  13. | Failure of error : exn
  14. override x.ToString() =
  15. match x with
  16. | Success v -> "Success(" + v.ToString() + ")"
  17. | Failure e -> "Failure(" + e.ToString() + ")"
  18.  
  19. [<RequireQualifiedAccess>]
  20. [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  21. module Immediate =
  22. let inline ofValue x = Success x
  23.  
  24. let inline zero<'T> = Unchecked.defaultof<'T> |> ofValue
  25.  
  26. let create (ctor : unit -> 'T) =
  27. try Success (ctor ())
  28. with e -> Failure e
  29.  
  30. let inline ofException x = Failure x
  31.  
  32. let inline isSuccess x =
  33. match x with
  34. | Success _ -> true
  35. | _ -> false
  36.  
  37. let inline isFailure x =
  38. match x with
  39. | Failure _ -> true
  40. | _ -> false
  41.  
  42. let get =
  43. function
  44. | Success v -> v
  45. | Failure e -> raise e
  46.  
  47. let toAsync =
  48. function
  49. | Success v -> async { return v }
  50. | Failure e -> async { return raise e }
  51.  
  52. let toTask =
  53. function
  54. | Success v -> task { return v }
  55. | Failure e -> task { return raise e }
  56.  
  57. let toLazy =
  58. function
  59. | Success v -> Lazy.CreateFromValue(v)
  60. | Failure e -> Lazy.Create(fun () -> raise e)
  61.  
  62. let map (fn : 'T -> 'U) =
  63. function
  64. | Success v -> Success (fn v)
  65. | Failure e -> Failure e
  66.  
  67. let bind (fn : 'T -> Immediate<'U>) =
  68. function
  69. | Success v -> fn v
  70. | Failure e -> Failure e
  71.  
  72. let fold (folder : 'State -> 'T -> 'State) (zero : 'State) =
  73. function
  74. | Success v -> Success (folder zero v)
  75. | Failure e -> Failure e
  76.  
  77. let rescue (fn : exn -> 'T) =
  78. function
  79. | Success v -> Success v
  80. | Failure e ->
  81. try Success (fn e)
  82. with e -> Failure e
  83.  
  84. [<Struct>]
  85. type Awaitable<'T> =
  86. | Async of async : Async<'T>
  87. | Task of task : Task<'T>
  88. override x.ToString() =
  89. match x with
  90. | Async a -> "Async(" + a.ToString() + ")"
  91. | Task t -> "Task(" + t.ToString() + ")"
  92.  
  93. [<RequireQualifiedAccess>]
  94. [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  95. module Awaitable =
  96. let inline ofValue x = async { return x } |> Async
  97.  
  98. let inline zero<'T> = Unchecked.defaultof<'T> |> ofValue
  99.  
  100. let inline isAsync x =
  101. match x with
  102. | Async _ -> true
  103. | _ -> false
  104.  
  105. let inline isTask x =
  106. match x with
  107. | Task _ -> false
  108. | _ -> true
  109.  
  110. let inline ofAsync x = Async x
  111.  
  112. let inline ofTask x = Task x
  113.  
  114. let ofPlainTask (x : Task) = task { do! x } |> Task
  115.  
  116. let ofEvent x = Async.AwaitEvent(x) |> Async
  117.  
  118. let ofLazy (x : Lazy<'T>) = async { return x.Value } |> Async
  119.  
  120. let ofException (x : exn) = async { return raise x } |> Async
  121.  
  122. let inline ofImmediate x =
  123. match x with
  124. | Success x -> ofValue x
  125. | Failure e -> ofException e
  126.  
  127. let get =
  128. function
  129. | Async a -> Async.RunSynchronously(a)
  130. | Task t -> t.Result
  131.  
  132. let toImmediate x =
  133. try Success (get x)
  134. with e -> Failure e
  135.  
  136. let toAsync =
  137. function
  138. | Async a -> a
  139. | Task t -> Async.AwaitTask(t)
  140.  
  141. let toTask =
  142. function
  143. | Async a -> task { return! a }
  144. | Task t -> t
  145.  
  146. let toLazy x = Lazy.Create(fun () -> get x)
  147.  
  148. let map (fn : 'T -> 'U) =
  149. function
  150. | Async a ->
  151. async {
  152. let! value = a
  153. return fn value
  154. } |> Async
  155. | Task t ->
  156. task {
  157. let! value = t
  158. return fn value
  159. } |> Task
  160.  
  161. let bind (fn : 'T -> Awaitable<'U>) =
  162. function
  163. | Async a ->
  164. async {
  165. let! value = a
  166. return! toAsync (fn value)
  167. } |> Async
  168. | Task t ->
  169. task {
  170. let! value = t
  171. return! toTask (fn value)
  172. } |> Task
  173.  
  174. let fold (folder : 'State -> 'T -> 'State) (zero : 'State) =
  175. function
  176. | Async a ->
  177. async {
  178. let! value = a
  179. return folder zero value
  180. } |> Async
  181. | Task t ->
  182. task {
  183. let! value = t
  184. return folder zero value
  185. } |> Task
  186.  
  187. let rescue (fn : exn -> 'T) =
  188. function
  189. | Async a ->
  190. async {
  191. try return! a
  192. with e -> return fn e
  193. } |> Async
  194. | Task t ->
  195. task {
  196. try return! t
  197. with e -> return fn e
  198. } |> Task
  199.  
  200. let private collectParallelAsync (values : Awaitable<'T> []) =
  201. Array.map toAsync values |> Async.Parallel |> Async
  202.  
  203. let private collectParallelTask (values : Awaitable<'T> []) =
  204. Array.map toTask values |> Task.WhenAll |> Task
  205.  
  206. let collectParallel (values : Awaitable<'T> []) =
  207. if Array.forall isTask values
  208. then collectParallelTask values
  209. else collectParallelAsync values
  210.  
  211. let private collectSequentialAsync (values : Awaitable<'T> []) =
  212. async {
  213. let results = Array.zeroCreate values.Length
  214. let asyncValues = values|> Array.map toAsync
  215. for i = 0 to values.Length - 1 do
  216. let! value = asyncValues.[i]
  217. results.[i] <- value
  218. return results
  219. } |> Async
  220.  
  221. let private collectSequentialTask (values : Awaitable<'T> []) =
  222. task {
  223. let results = Array.zeroCreate values.Length
  224. let asyncValues = values|> Array.map toAsync
  225. for i = 0 to values.Length - 1 do
  226. let! value = asyncValues.[i]
  227. results.[i] <- value
  228. return results
  229. } |> Task
  230.  
  231. let collectSequential (values : Awaitable<'T> []) =
  232. if Array.forall isTask values
  233. then collectSequentialTask values
  234. else collectSequentialAsync values
  235.  
  236. let appendParallel (values : Awaitable<'T []> []) =
  237. values
  238. |> collectParallel
  239. |> map (Array.fold Array.append [||])
  240.  
  241. let appendSequential (values : Awaitable<'T []> []) =
  242. values
  243. |> collectSequential
  244. |> map (Array.fold Array.append [||])
  245.  
  246. [<Struct>]
  247. type Value<'T> =
  248. | Immediate of immediateValue : Immediate<'T>
  249. | Awaitable of awaitableValue : Awaitable<'T>
  250. | Lazy of lazyValue : Lazy<'T>
  251. override x.ToString() =
  252. match x with
  253. | Immediate i -> "Immediate(" + i.ToString() + ")"
  254. | Awaitable a -> "Awaitable(" + a.ToString() + ")"
  255. | Lazy l -> "Lazy(" + l.ToString() + ")"
  256.  
  257. type 'T value = Value<'T>
  258.  
  259. [<RequireQualifiedAccess>]
  260. [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  261. module Value =
  262. let inline ofValue x = Immediate.ofValue x |> Immediate
  263.  
  264. let inline zero<'T> = Unchecked.defaultof<'T> |> ofValue
  265.  
  266. let inline isImmediate x =
  267. match x with
  268. | Immediate _ -> true
  269. | _ -> false
  270.  
  271. let inline isAwaitable x =
  272. match x with
  273. | Awaitable _ -> true
  274. | _ -> false
  275.  
  276. let inline isLazy x =
  277. match x with
  278. | Lazy _ -> true
  279. | _ -> false
  280.  
  281. let inline ofImmediate x = Immediate x
  282.  
  283. let inline ofAwaitable x = Awaitable x
  284.  
  285. let inline ofLazy x = Lazy x
  286.  
  287. let inline ofException x = Immediate.ofException x |> Immediate
  288.  
  289. let inline ofAsync x = Awaitable.ofAsync x |> Awaitable
  290.  
  291. let inline ofTask x = Awaitable.ofTask x |> Awaitable
  292.  
  293. let inline ofPlainTask x = Awaitable.ofPlainTask x |> Awaitable
  294.  
  295. let get =
  296. function
  297. | Immediate x -> Immediate.get x
  298. | Awaitable x -> Awaitable.get x
  299. | Lazy l -> l.Value
  300.  
  301. let toImmediate =
  302. function
  303. | Immediate x -> x
  304. | Awaitable x -> Awaitable.toImmediate x
  305. | Lazy l -> Immediate.create l.Force
  306.  
  307. let toAwaitable =
  308. function
  309. | Immediate x -> Awaitable.ofImmediate x
  310. | Awaitable x -> x
  311. | Lazy l -> Awaitable.ofLazy l
  312.  
  313. let toLazy =
  314. function
  315. | Immediate x -> Immediate.toLazy x
  316. | Awaitable x -> Awaitable.toLazy x
  317. | Lazy l -> l
  318.  
  319. let toAsync =
  320. function
  321. | Immediate x -> Immediate.toAsync x
  322. | Awaitable x -> Awaitable.toAsync x
  323. | Lazy l -> async { return l.Value }
  324.  
  325. let toTask =
  326. function
  327. | Immediate x -> Immediate.toTask x
  328. | Awaitable x -> Awaitable.toTask x
  329. | Lazy l -> task { return l.Value }
  330.  
  331. let map (fn : 'T -> 'U) =
  332. function
  333. | Immediate x -> x |> Immediate.map fn |> Immediate
  334. | Awaitable x -> x |> Awaitable.map fn |> Awaitable
  335. | Lazy l -> l |> Lazy.map fn |> Lazy
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement