Notational syntax sugar for list and do notation - vector

So I've noticed that in Idris if you define your own list or vector like type — for example the following type I've found to be useful:
data HFVec : (f : Type -> Type) -> (n : Nat) -> Vec n Type -> Type where
Nil : HFVec f Z []
(::) : (a : f t) -> HFVec f n ts -> HFVec f (S n) (t :: ts)
— then you get list syntax for free:
test : HFVec List 2 [Int, String]
test = [[3], [""]]
I assume this is done when you have a constructor named ::, but I don't know for certain. In the same way you get do-notation if you have a constructor named >>= even if there is no monad implementation:
data Test : Type -> Type where
Pure : a -> Test a
(>>=) : Test a -> (a -> Test b) -> Test b
test : Test Int
test = do
Pure 1
x <- Pure 2
Pure x
This is a pretty cool feature, the only thing is I have not found it documented anywhere. It would be good to know exactly how these mechanisms work so one can know under exactly what circumstances they can be expected to work. Also, are these kind of rules the privilege of the compiler, or can the user make them with the syntax and dsl features?

Related

Why does Idris 2 fail to resolve constraints with function composition in this trivial example?

I have encountered a problem with some code I am trying to write in Idris 2. I would like to resolve this issue, but more importantly, I wish to understand it more deeply and develop some skills in diagnosing such issues in general.
I have distilled the problem to the following relatively trivial example:
data D : Nat -> Type where
V : (n : Nat) -> D n
d : (n : Nat) -> D n
d n = V n
f : D n -> String
f (V n) = show n
t : Nat -> String
t = f . d
The definition of t fails type checking with the following output:
Error: While processing right hand side of t. Can't solve constraint between: ?n [no locals in scope] and n.
Test:11:9--11:10
07 | f : D n -> String
08 | f (V n) = show n
09 |
10 | t : Nat -> String
11 | t = f . d
Some experimentation has revealed that the following alternative definitions for t also fail type checking:
t : Nat -> String
t n = (f . d) n
t : Nat -> String
t = \n => (f . d) n
While these alternatives type check successfully:
t : Nat -> String
t n = f (d n)
t : Nat -> String
t = \n => f (d n)
I am endeavouring to learn Idris (for the second time), and so while I could move on with the definitions which don't involve function composition, I would like to improve my understanding.
It seems to me that the definitions which pass type checking are simply syntactic alternatives with identical semantics and behaviour, and I don't understand why the function composition definitions fail type checking. I would also like to understand the particular error message the type checker reports, so that I can deepen my understanding and resolve similar type checking errors in the future.
I have a few broad questions:
How should I interpret the error reported by the type checker in this example, and how can I gather more information about the ?n and n types mentioned? I particularly welcome any advice or tips on how to go about understanding and resolving such an error (teach a man to fish, as the saying goes).
Why do the definitions involving function composition fail type checking?
What is the best solution for this example? Should I just use a definition which does not involve function composition? Is there a better alternative?
Let look at the types involved
Prelude.. : (b -> c ) -> (a -> b ) -> a -> c
f : D n -> String
d : (n : Nat) -> D n
The problem is:
(a -> b )
(n : Nat) -> D n
cannot be unified because (a -> b) does not allow the value of the argument to determine the type of return value.

Order of implicit arguments in idris

How does the order of implicit arguments affect idris?
I just read this post and I got curious about MkPair's type signature.
I tried MkPair 10 on REPL and I got
(input):Can't infer argument B to Builtins.MkPair
And this is exactly what I expected. From its type signature Builtins.MkPair : {A : Type} -> {B : Type} -> (a : A) -> (b : B) -> (A, B), I have to pass B(whether it's implicit or explicit) before apply a value for a.
At the same time, I expected q 10 to work, cause its type is q : {A : Type} -> (a : A) -> {B : Type} -> (b : B) -> (A, B) which tells me that I don't need any value for B before I apply a value for A and a.
But it also failed with the same message!
(input):Can't infer argument B to Main.q
What happens to q?
And I have one more question . Before I found that q worked neither, I was gonna ask the reason that Idris compiler prefers MkPair's signature to q's one. MkPair looks unnecessarily eager to me. Why does it demand B too early?
Without any context to guide the compiler, I guess Idris stays true to its eager by default attitude and tries to infer all the implicit arguments that appear before the last "explicit" one specified, before doing automatic partial application.
Note that you can suppress this behavior by placing the expression in an appropriately typed hole:
the ({b : Type} -> b -> (Nat, b)) (q 10)
-- or
r : {b : Type} -> b -> (Nat, b)
r = q 10

Function cannot use type inference, but I don't understand why

So here is my goofy sandbox to play with Applicatives in PureScript
module Main where
import Debug.Trace
data Foo a
= Foo a
instance showFoo :: (Show a) => Show (Foo a) where
show (Foo a) = "I pity da (Foo " ++ (show a) ++ ")"
instance functorFoo :: Functor Foo where
(<$>) f (Foo a) = Foo (f a)
instance applyFoo :: Apply Foo where
(<*>) (Foo a) (Foo b) = Foo (a b)
m :: Number -> Number -> Number -> Number
m x y z = x * y - z
main = trace <<< show $ m <$> Foo 14
<*> Foo 2
<*> Foo 5
The above works fine, but if I remove:
m :: Number -> Number -> Number -> Number
it does not compile
Error at pure.purs line 18, column 1:
Error in declaration m
No instance found for Prelude.Num u1150
However (+) and (-) are both of type
forall a. (Prelude.Num a) => a -> a -> a
Why can't Number be inferred?
The reality is that when learning PureScript and coming from a dynamic language (JavaScript), I run into type errors frequently. Developing skills in diagnosing and understanding these errors is challenging without a grasp of when inference can occur and when it can't. Otherwise I will have to write types every single time in order to feel confident in my code (lameness).
This is because at the moment the compiler can't infer typeclass constraints, and as you noted the arithmetic operators are all defined in the Num typeclass.
The type that would be inferred for m (if the compiler could) would be something like:
m :: forall a. (Num a) => a -> a -> a -> a
On your second point typing top level declarations is considered good style anyway, as it helps to document your code: see here for a fuller explanation.

F# - Treating a function like a map

Long story short, I came up with this funny function set, that takes a function, f : 'k -> 'v, a chosen value, k : 'k, a chosen result, v : 'v, uses f as the basis for a new function g : 'k -> 'v that is the exact same as f, except for that it now holds that, g k = v.
Here is the (pretty simple) F# code I wrote in order to make it:
let set : ('k -> 'v) -> 'k -> 'v -> 'k -> 'v =
fun f k v x ->
if x = k then v else f x
My questions are:
Does this function pose any problems?
I could imagine repeat use of the function, like this
let kvs : (int * int) List = ... // A very long list of random int pairs.
List.fold (fun f (k,v) -> set f k v) id kvs
would start building up a long list of functions on the heap. Is this something to be concerned about?
Is there a better way to do this, while still keeping the type?
I mean, I could do stuff like construct a type for holding the original function, f, a Map, setting key-value pairs to the map, and checking the map first, the function second, when using keys to get values, but that's not what interests me here - what interest me is having a function for "modifying" a single result for a given value, for a given function.
Potential problems:
The set-modified function leaks space if you override the same value twice:
let huge_object = ...
let small_object = ...
let f0 = set f 0 huge_object
let f1 = set f0 0 small_object
Even though it can never be the output of f1, huge_object cannot be garbage-collected until f1 can: huge_object is referenced by f0, which is in turn referenced by the f1.
The set-modified function has overhead linear in the number of set operations applied to it.
I don't know if these are actual problems for your intended application.
If you wish set to have exactly the type ('k -> 'v) -> 'k -> 'v -> 'k -> 'v then I don't see a better way(*). The obvious idea would be to have a "modification table" of functions you've already modified, then let set look up a given f in this table. But function types do not admit equality checking, so you cannot compare f to the set of functions known to your modification table.
(*) Reflection not withstanding.

OCaml: Is there a function with type 'a -> 'a other than the identity function?

This isn't a homework question, by the way. It got brought up in class but my teacher couldn't think of any. Thanks.
How do you define the identity functions ? If you're only considering the syntax, there are different identity functions, which all have the correct type:
let f x = x
let f2 x = (fun y -> y) x
let f3 x = (fun y -> y) (fun y -> y) x
let f4 x = (fun y -> (fun y -> y) y) x
let f5 x = (fun y z -> z) x x
let f6 x = if false then x else x
There are even weirder functions:
let f7 x = if Random.bool() then x else x
let f8 x = if Sys.argv < 5 then x else x
If you restrict yourself to a pure subset of OCaml (which rules out f7 and f8), all the functions you can build verify an observational equation that ensures, in a sense, that what they compute is the identity : for all value f : 'a -> 'a, we have that f x = x
This equation does not depend on the specific function, it is uniquely determined by the type. There are several theorems (framed in different contexts) that formalize the informal idea that "a polymorphic function can't change a parameter of polymorphic type, only pass it around". See for example the paper of Philip Wadler, Theorems for free!.
The nice thing with those theorems is that they don't only apply to the 'a -> 'a case, which is not so interesting. You can get a theorem out of the ('a -> 'a -> bool) -> 'a list -> 'a list type of a sorting function, which says that its application commutes with the mapping of a monotonous function.
More formally, if you have any function s with such a type, then for all types u, v, functions cmp_u : u -> u -> bool, cmp_v : v -> v -> bool, f : u -> v, and list li : u list, and if cmp_u u u' implies cmp_v (f u) (f u') (f is monotonous), you have :
map f (s cmp_u li) = s cmp_v (map f li)
This is indeed true when s is exactly a sorting function, but I find it impressive to be able to prove that it is true of any function s with the same type.
Once you allow non-termination, either by diverging (looping indefinitely, as with the let rec f x = f x function given above), or by raising exceptions, of course you can have anything : you can build a function of type 'a -> 'b, and types don't mean anything anymore. Using Obj.magic : 'a -> 'b has the same effect.
There are saner ways to lose the equivalence to identity : you could work inside a non-empty environment, with predefined values accessible from the function. Consider for example the following function :
let counter = ref 0
let f x = incr counter; x
You still that the property that for all x, f x = x : if you only consider the return value, your function still behaves as the identity. But once you consider side-effects, you're not equivalent to the (side-effect-free) identity anymore : if I know counter, I can write a separating function that returns true when given this function f, and would return false for pure identity functions.
let separate g =
let before = !counter in
g ();
!counter = before + 1
If counter is hidden (for example by a module signature, or simply let f = let counter = ... in fun x -> ...), and no other function can observe it, then we again can't distinguish f and the pure identity functions. So the story is much more subtle in presence of local state.
let rec f x = f (f x)
This function never terminates, but it does have type 'a -> 'a.
If we only allow total functions, the question becomes more interesting. Without using evil tricks, it's not possible to write a total function of type 'a -> 'a, but evil tricks are fun so:
let f (x:'a):'a = Obj.magic 42
Obj.magic is an evil abomination of type 'a -> 'b which allows all kinds of shenanigans to circumvent the type system.
On second thought that one isn't total either because it will crash when used with boxed types.
So the real answer is: the identity function is the only total function of type 'a -> 'a.
Throwing an exception can also give you an 'a -> 'a type:
# let f (x:'a) : 'a = raise (Failure "aaa");;
val f : 'a -> 'a = <fun>
If you restrict yourself to a "reasonable" strongly normalizing typed λ-calculus, there is a single function of type ∀α α→α, which is the identity function. You can prove it by examining the possible normal forms of a term of this type.
Philip Wadler's 1989 article "Theorems for Free" explains how functions having polymorphic types necessarily satisfy certain theorems (e.g. a map-like function commutes with composition).
There are however some nonintuitive issues when one deals with much polymorphism. For instance, there is a standard trick for encoding inductive types and recursion with impredicative polymorphism, by representing an inductive object (e.g. a list) using its recursor function. In some cases, there are terms belonging to the type of the recursor function that are not recursor functions; there is an example in §4.3.1 of Christine Paulin's PhD thesis.

Resources