-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstance.html
49 lines (42 loc) · 4.6 KB
/
instance.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html><html lang="en"><head><title>Instance arguments | Novah language</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/css/main.css"><link rel="stylesheet" href="/css/prism.css"><link rel="icon" href="/img/novah.png"><script src="/js/main.js"></script><script src="/js/prism.js"></script></head><body><a id="skip-link" href="#main">Skip to main content</a><header><div class="header-content"><a href="/" aria-label="Novah homepage" class="header-title"><img src="/img/novah.svg" width="32" height="32" alt="logo" class="logo">Novah</a><a href="//github.com/stackoverflow/novah" class="source"><img src="/img/GitHub-Mark-Light-32px.png" width="16" height="16" alt="Github">Source</a></div><button onclick="onNavToggle()" aria-label="Menu" aria-haspopup="menu" aria-controls="nav" aria-expanded="false" class="nav-mobile closed"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16" class="nav-icon"><path fill-rule="evenodd" d="M2.5 11.5A.5.5 0 0 1 3 11h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4A.5.5 0 0 1 3 3h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"></path></svg></button></header><div id="content"><nav id="nav"><ul class="nav-list"><li aria-current="false" data-ref="menuitem" tabIndex="-1"><a href="/">Home</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/syntax">Syntax</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/types">Types</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/records">Records</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/pattern-matching">Pattern matching</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/interop">Java interoperability</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/computations">Computation expressions</a></li><li aria-current="page" data-ref="menuitem" tabIndex="null" class="nav-selected"><a href="/instance">Instance arguments</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/cli">Command line</a></li><li aria-current="false" data-ref="menuitem" tabIndex="null"><a href="/apidoc">API docs</a></li></ul></nav><main id="main"><h1 tabIndex="-1">Instance arguments</h1><p>Parametric polymorphism (generics) can help you create functions that take or return any type.
But sometimes this is too broad and you want functions that only work for a set of types.
For this you need ad hoc polymorphism.
</p><p>Imagine you need a function + that sums two numbers. This function should work for numeric types only.
There's no way to implement such a function using generics alone.
Instance arguments to the rescue!
Instance arguments allow you to create something similiar to type classes and their instances.
</p><p class="visually-hidden">Begin code:</p><pre><code class="language-novah">module instanceargs
// define your type class
pub
type Plus a = Plus { plus : a -> a -> a }
// the actual function
(+) : {{ Plus a }} -> a -> a -> a
(+) {{Plus {plus}}} x y = plus x y
// instances can be created in any module
// and will always be searched if they are in the current context
pub instance
plusInt : Plus Int
plusInt = Plus { plus: \x y -> Java.sumInt(x, y) }
// using it
theSum = 3 + 4</code></pre><p class="visually-hidden">End code.</p><p>Any type can be used as an instance argument as long as it's a named type.
You can use the double bracket syntax to annotate a function parameter as an instance argument.
These arguments can be explicitily passed to a function using double bracket syntax.
</p><p class="visually-hidden">Begin code:</p><pre><code class="language-novah">module instanceargs
// creating a function that take an instance argument
showAndPrint : {{ Show a }} -> a -> Unit
showAndPrint {{Show showFun}} x = println (showFun x)
pub
main : Array String -> Unit
main _ =
// the compiler will search for the instance
showAndPrint 4
// explicitily passing the argument
showAndPrint {{showChar}} 'a'</code></pre><p class="visually-hidden">End code.</p><p>The Novah compiler can automatically infer the type of an instance argument if it's unambiguous.
</p><p class="visually-hidden">Begin code:</p><pre><code class="language-novah">module instanceargs
foo : Unit -> Unit
foo () =
// doesn't compile: cannot find Plus instance for x, y
let sum2 x y = x + y
// automatically infer the instance type
let sum {{_}} x y = x + y
println (sum 5.6 9.0)</code></pre><p class="visually-hidden">End code.</p></main></div></body></html>