Replies: 3 comments 12 replies
-
It seems like you understand
Line 365 in 39b4bec S there are no concrete things in Koka of kind h . It must be a type-variable, or global .
// Use `run` to dismiss the state effect
pub fun work-on-my-heap() : <console> ()
with run
work-on-any-heap()
pub fun main()
work-on-string-value("Hello")
work-on-int-value(2)
// work-on-global-heap()
work-on-my-heap() // No state effect observable
() |
Beta Was this translation helpful? Give feedback.
-
From all that info, I would like to try to give a short overview of how I understand kinds now in general and also with respect to Koka (including the syntax). I hope I got it right, and I'm also happy to be corrected where I'm wrong. There are values, types, and kinds. Each value is of a specific type and each type is of a specific kind. To denote a variable Most usual types we deal with in programming are of kind A function type (which is a value type and thus of kind Types are inhabited if there is at least one possible value of the type. Types that are inhabited are always of kind If a type has only one possible value, it is inhabited but practically carries no information. Koka comes with a So let's sum up some examples for value types, i.e. types of kind
As both the type of arguments and the type of a return value may be a function (functions are first-class values in Koka), we can also have more complex value types like:
Moreover, it's possible that functions are polymorphic, which means they accept values of arbitrary types as arguments and their return type may depend on those input types. When we use single lowercase letters, then Koka automatically treats these as type variables rather than specific types. For example To explicitly denote an identifier as a variable, we can use the The syntax when defining a function is slightly different. Both functions below have the same type: fun my-func<foo>( x : foo ) : foo
x
fun same-func( x : a ) : a
x When defining a function, the colon ( As we can have functions which expect or return polymorphic functions, it is also possible to use such polymorphic types as an argument or return type of a function. For example: fun some-func( pick : forall<a> (a, a, bool) -> a ) : console ()
println( pick(3, 7, True ).show() )
println( pick("Hello", "World", False ) )
pub fun main()
some-func( fn(x, y, b) if b then x else y ) Here, the So some more examples of value types (recall that all these are still of kind
Now all this is pretty complex already, but only covered types of kind Now how many other kinds are existing? There are the built-in types For example And example would be the following type: type one-or-two<a> :: V -> V
One ( only : a )
Two ( first : a, second : a ) It is optional to annotate the kind with We can also take two value types as arguments for such a type constructor: type different<a,b> :: (V,V) -> V
First ( only : a )
Second ( only : b )
Both ( first : a, second : b ) But we can also accept type constructors (e.g. a type of kind type nested<c,a> :: (V->V, V) -> V
Easy ( easy : a )
Complex ( complex : c<a> ) So just using the basic kind Now to the kinds These types aren't usually named so they don't need and cannot be referenced in code, with the exception that When a function's type signature includes types of kinds Effect rows (sets of effects, but each effect may appear more than once) are types of kind pub fun twice<effty::E,valty::V>(func : () -> effty valty) : effty (valty,valty)
(func(), func()) Or in short, using single letter variables: pub fun twice(func : () -> e v) : e (v,v)
(func(), func()) Until here, I covered the kinds However, I'm still confused about |
Beta Was this translation helpful? Give feedback.
-
In my previous post, I gave this example: pub fun twice<effty::E,valty::V>(func : () -> effty valty) : effty valty
func()
func() Now trying to modify it to: pub fun twice<atm::X,valty::V>(func : () -> <atm> valty) : <atm> (valty,valty)
(func(), func()) Gives the following compile error:
I learned earlier that
So does that mean -pub fun twice<atm::X,valty::V>(func : () -> <atm> valty) : <atm> (valty,valty)
+pub fun twice<atm::HX,valty::V>(func : () -> <atm> valty) : <atm> (valty,valty)
(func(), func()) Now I get:
Let's see if HX can be used at all. Apparently the following compiles: effect my-effect1 :: HX
fun log1 ( msg : string ) : ()
effect my-effect2 :: (E,V) -> V
fun log2 ( msg : string ) : () Okay, so if I declare an effect, that effect has kind I tried to read the notes in
Side note: I assume that the kind of That "answer context" is explained as:
Okay, so when we have some type (say That makes sense to me now, but… what I wonder is whether this is just some language internals? Or does it ever make sense to actually use values of these type in Koka "user" code? E.g. would I ever use the I would like to understand how much of this is actually internals, and which of it is intended to be used by user code? Also, how does Sorry for my confusion. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I would like to better understand kinds and how they are used.
The book lists some kinds, which I will try to enrich with examples:
V
: value type, e.g.int
orstring
X
: (atomic) effect type, e.g.exn
ordiv
E
: effect row, e.g.total
,pure
, or<ndet,console>
H
: heap type, e.g.global
(and any other!?)S
: scope type (which is only created implicitly by ax <- named handler
expression?)P
: predicate type (not sure what that is and if it's used somewhere?)HX
: "handled effect type" (which means?), likely defined as some sort of kind-alias(?) for(E,V) -> V
HX1
: "handled linear effect type"If I write:
Then I get:
But I think
goody
should beHX1
andmoody
should beHX
? Why do both show the same kind?Now this makes me also wonder about the
->
notation. As far as I understand, for types it denotes functions:string -> int
is the type of a function that gets astring
and returns anint
.Also, such a function again has the kind
V
, it seems:But even functions involving effects seem to be of kind
V
:I guess that's because those are first-class values (hence
V
), like any other value of a primitive datatype such asint
?When using the
->
operator for kinds, it means it's some sort of higher-ranked "function"(?), like a type constructor, right? E.g.(V,V) -> V
is a type constructor that takes two (arbitrary?) types of kindV
and returns a type of kindV
. For example:I feed in a pair of (value-)types and get another (value-)type back. As far as I understand, there is no restriction on the value types I feed into
oneortwo
: the only restriction is that it's value types, i.e.int
orstring -> int
or() -> exn int
and not, for exampleexn
, which would be of kindX
(orE
depending on context?).But then, I don't understand the notion of
(E, V) -> V
. Does it meanmoody
from above can take any (arbitrary?) row of effects and any (arbitrary?) value-type (such as a function type) and return another value-type (such as a modified function type)? Or how does it work? And what role does the row of effects play there? Could someone point me to a particular example which types of kindE
andV
could be fed in, and which type of kindV
could be returned?Another issue I don't understand is what the
H
kind really is.Consider I have a function:
This has type:
Thus I assume I can use this function with any heap
h
, right? And I can use it for different heaps in the same program? But how do I create such a heap? Is it as easy as writing:? Or do I have to use a specific function or keyword for it? If yes, which one(s)?
I tried some things, and it confused me more than giving answers:
Running this as is, I get
5
as a result. But if I uncomment the last line:Then I get:
Why does the compiler expect these effect rows to be identical? It also doesn't expect the
work-on-string-value
andwork-on-int-value
functions to be identical.If I only comment in the last line:
Then I get:
Is there any way to use other heaps than
global
? How does this really work and is there some documentation on it, or example code?I'm sorry if I maybe misunderstand quite a lot as of yet. I'd appreciate any help to get a better overview on the topic of "kinds" in Koka.
Beta Was this translation helpful? Give feedback.
All reactions