Although Idris is dependently typed, where values can be used freely in types, it still differentiate function id and functor Identity. Why can't I define Functor instances on id:
Functor id where
map = id
The type of id is id : a -> a, why can't a be unified with Type, so that map #{Functor id} has type (a -> b) -> id a -> id b, which is just (a -> b) -> a -> b
I understand that Identity is a type wrapper but why do I need a separate id at type level, just to enable the implementation of typeclass instances.
The only difference of Identity and id is that Identity a cannot be evaluated to a, but it’s still a Type -> Type function, same as id {a=Type} in type.
id is a function which returns its input value as the result. When you need a function that does nothing to its input except return the same value, then use id.
Identity is a simple type wrapper which wraps a type t to produce a new type Identity t, where a value of type Identity t is a record containing just one value of the original wrapped type t.
Because Identity is an algebraic data type, it can implement an interface in Idris. In particular it implements Monad.
Sometimes one can define a type constructor that constructs types which implement Monad, by first defining a monad transformer that takes a monadic type as one of its parameters. To provide an arbitrary non-monad type as a parameter to such a constructor, first wrap the non-monad type using the Identity type constructor.
For an example, see the library module Control.Monad.Writer.
Related
The Map interface in Kotlin (using V1.6.21) has a signature of
interface Map<K, out V>
Why is K invariant instead of covariant (out K)?
The documentation of type parameter K says:
The map is invariant in its key type, as it can accept key as a parameter (of containsKey for example) and return it in keys set.
However, interface Set is covariant in the element type, so the the last part ("return it in keys set") is not applicable, at least not immediately.
Further, the type parameter K is used only at occurrences where the map state is not modified, for lookup purposes (methods containsKey, get, getOrDefault). At these places, isn't it safe to use #UnsafeVariance? After all, that same technique was employed to Map's value type parameter V, for example in containsValue, to allow making V covariant.
My guess would be that using a Map<KSubtype, V> as a Map<KSupertype, V> (where KSubtype : KSupertype) does not really make a lot of sense because the former, by construction, cannot contain entries with keys other than KSubtype.
So a proper implementation should return null from all calls to get(kSupertype) as well as return false from those to containsKey(kSupertype).
In the case of Set<out E> it's only the contains function that needs unsafe variance, and Map would also require unsafe variance on get. This might have been too much of a peculiarity to support, compared to the value of supporting the use case.
I want to use the Scan() function from the sql package for executing a select statement that might (or not) return multiple rows, and return these results in my function.
I´m new to Golang generics, and am confused about how to achieve this.
Usually, we would use the Scan function on a *sql.Rows and provide the references to all fields of our expected 'result type' we want to read the rows into, e.g.:
var alb Album
rows.Scan(&alb.ID, &alb.Title, &alb.Artist,
&alb.Price, &alb.Quantity)
where Album is a struct type with those five fields shown.
Now, for the purpose of not writing a similar function N times for every SQL table I have, I want to use a generic type R instead. R is of generic interface type Result, and I will define this type as one of N different structs:
type Result interface {
StructA | StructB | StructC
}
func ExecSelect[R Result](conn *sql.DB, cmd Command, template R) []R
How can I now write rows.Scan(...) to apply the Scan operation on all fields of my struct of R´s concrete type? e.g. I would want to have rows.Scan(&res.Field1, &res.Field2, ...) where res is of type R, and Scan should receive all fields of my current concrete type R. And do I actually need to provide a 'template' as argument of R´s concrete type, so that at runtime it becomes clear which struct is now relevant?
Please correct me on any mistake I´m making considering the generics.
This is a poor use case for generics.
The arguments to the function sql.Rows.Scan are supposed to be the scan destinations, i.e. your struct fields, one for each column in the result set, and within the generic function body you do not have access to the fields of R type parameter.
Even if you did, the structs in your Result constraint likely have different fields...? So how do you envision writing generic code that works with different fields?
You might accomplish what you want with a package that provides arbitrary struct scanning like sqlx with facilities like StructScan, but that uses reflection under the hood to map the struct fields into sql.Rows.Scan arguments, so you are not getting any benefit at all with generics.
If anything, you are making it worse, because now you have the additional performance overheads of using type parameters.
I'm working on porting GHC/Arr.hs into Frege.
Array is defined:
data Array i e = Array{u,l::i,n::Int,elems::(JArray e)}
There is function:
amap :: (Ix i, ArrayElem e) => (a -> b) -> Array i a -> Array i b
Now, I don't know how to define Functor instance for it, because
instance (Ix i) => Functor (Array i) where
fmap = amap
But compiler complains that inferred type is more constrained that expected, what seems true. Can I make Array an functor with restrction for functions ArrayElem -> ArrayElem?
No, this is not possible.
If you base Array on JArray and want a functor instance, you must not use any functions that arise the ArrayElem (or any other additional) context.
Another way to say this is that you cannot base Array on type safe java arrays, but must deal with java arrays of type Object[]. Because, as you have without doubt noted, the ArrayElem type class is just a trick to be able to provide the correct java type on creation of a java array. This is, of course, important for interfacing with Java and for performance reasons.
Note that there is another problem with type safe java arrays. Let's say we want to make an array of Double (but the same argument holds for any other element type). AFAIK, Haskell mandates that Arrays elements must be lazy. Hence we really cannot use the java type double[] (to which JArray Double would be the Frege counterpart) to model it. Because, if we would do this, every array element would have to be evaluated as soon as it is set.
For this reason, I suggest you use some general custom array element type, like
data AElem a = AE () a
mkAE = A ()
unAE (AE _ x) = x
derive ArrayElement AElem
and change your definition:
data Array i e = Array{u,l::i,n::Int,elems::(JArray (AElem e))}
Now, your functor instance can be written, because the ArrayElem constraint does not arise, because when you access the elems array, the compiler knows that you have AElem elements and can and will supply the correct instance.
In addition, construction of AElems and usage of AElems as actual array elements does not impose strictness on the actual value.
Needless to say, the user of the Array module should not (need to) know about those implementation details, that is, the AElem type.
I know it's possible to defer the definition of procedures from an abstract type to its derived types. Is it possible to include 'deferred' data in an abstract type, i.e., data whose type and value is only defined in derived classes?
The closest question I found on stackoverflow was here. It does not address my needs.
If clarification is needed, please ask. Many thanks.
There's no straightforward way to defer the definition of a data component of an (abstract) derived type as there is for procedure components, so no declaration such as
type(magic), deferred :: element
which can be overridden by a concrete declaration in an extended type. I think the easy (?) workaround would be to use class in the declaration. For ultimate flexibility you could use an unlimited polymorphic component, eg
type :: stype
class(*), allocatable :: element
end type style
What you can't then do is specify the type in a concrete extended type with a (re-)declaration something like
type, extends(stype) :: mstype
integer :: element
end type mstype
Instead, if you want to define an extended type which has an integer element you would create the type and write a constructor for it that ensures its element is allocated with type integer.
If your requirements are more modest the 2003 feature of parameterised derived types might satisfy you, but as far as I know only the Cray and IBM XL compilers implement that yet.
I'm trying to implement the classical tree structure in frege, which works nicely as long as I don't use "derive":
data Tree a = Node a (Tree a) (Tree a)
| Empty
derive Show Tree
gives me
realworld/chapter3/E_Recursive_Types.fr:7: kind error,
type constructor `Tree` has kind *->*, expected was *
Is this not supported or do I have to declare it differently?
Welcome to the world of type kinds!
You must give the full type of the items you want to show. Tree is not a type (kind *), but something that needs a type parameter to become one (kind * -> *).
Try
derive Show (Tree a)
Note that this is shorthand for
derive Show (Show a => Tree a)
which resembles the fact that, to show a tree, you need to also know how to show the values in the tree (at least, the code generated by derive will need to know this - of course, one could write an instance manually that prints just the shape of the tree and so would not need it).
Generally, the kind needed in instances for every type class is fixed. The error message tells you that you need kind * for Show.
EDIT: eliminate another possible misconception
Note that this has nothing to do with your type being recursive. Let's take, for example, the definition of optional values:
data Maybe a = Nothing | Just a
This type is not recursive, and yet we still cannot say:
derive Show Maybe -- same kind error as above!!
But, given the following type class:
class ListSource c -- things we can make a list from
toList :: c a -> [a]
we need say:
instance ListSource Maybe where
toList (Just x) = [x]
toList Nothing = []
(instanceand derive are equivalent for the sake of this discussion, both make instances, the difference being that derive generates the instance functions automatically for certain type classes.)
It is, admittedly, not obvious why it is this way in one case and differntly in the other. The key is, in every case the type of the class operation we want to use. For example, in class Show we have:
class Show s where
show :: s -> String
Now, we see that the so called class type variable s (which represents any future instantiated type expression) appears on its own on the left of the function array. This, of course, indicates that s must be a plain type (kind *), because we pass a value to show and every value has per definition a type of kind *. We can have values of types Int or Maybe Int or Tree String, but no value ever has a type Maybe or Tree.
On the other hand, in the definition of ListSource, the class type variable c is applied to some other type variable a in the type of toList, which also appears as list element type. From the latter, we can conclude, that a has kind * (because list elements are values). We know, that the type to the left and to the right of a function arrow must have kind * also, since functions take and return values. Therefore, c a has kind *. Thus, c alone is something that, when applied to a type of kind * yields a type of kind *. This is written * -> *.
This means, in plain english, when we want to make an instance for ListSource we need the type constructor of some "container" type that is parameterized with another type. Tree and Maybe would be possible here, but not Int.