Last active
October 1, 2021 19:23
-
-
Save maedoc/cab49e0916c49ff1dd14aaacb8fd480b to your computer and use it in GitHub Desktop.
Polymorphic arithmetic in Futhark
This file contains hidden or 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
-- was not clear to me from the user guide how this is supposed to work | |
-- when in fact it's straightforward | |
-- put the needed arithmetic ops in an "interface" / "concept" | |
module type arith = { | |
type t | |
val i32 : i32 -> t | |
val * : t -> t -> t | |
} | |
-- put the functions that should be "templated" | |
-- in their own module parametrized by the above interface: | |
module algo (N:arith) = { | |
open N -- this may bring more names into scope than we want | |
let f (x:t) (y:[]t): []t = map (\y -> x * y * (i32 1)) y | |
} | |
-- if the functions use multiples types in arithmetic e.g. indexing | |
-- then it may be easier to keep the module parameter explicit: | |
module algo2 (R:arith) = { | |
let f [n] (x:[n]R.t): [n]R.t = iota (n - 1) | |
|> map (\i -> (x[i+1] R.* x[i])) | |
|> ([R.i32 0]++) :> [n]R.t | |
} | |
-- dense math can use syntax R.(x + y * z) to keep it readable | |
-- maybe define a custom type & arithmetic | |
module ratio = { | |
type t = (i32, i32) | |
let i32 (i:i32): t = (i, 1) | |
let (*) (l:t) (r:t) = (l.0 * l.1, l.0 * l.1) | |
} | |
-- instantiate the algorithms for specific implementations | |
module u1 = algo { open f64 } | |
module u2 = algo ratio | |
-- profit | |
let main = ( | |
u1.f 1f64 [0f64, 1f64], | |
u2.f (1i32,2i32) [(2i32,2i32), (4i32,-1i32)] | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment