Parametrising over "higher-kinded" types in Idris - monads

I just started playing around with Idris, and tried shoe-horning some Haskell machines into it:
namespace works
data Auto a b = AutoC (a -> (b, Auto a b))
const_auto : b -> Auto a b
const_auto b = AutoC (\_ => (b, const_auto b))
However, I'd like now to generalize Auto a b to AutoM m a b to take an extra parameter so it can generate its output monadically, with m being the monad. My intuition would have been that m would have type Type -> Type, but then the type-checker complains that that doesn't match (Type, Type) -> Type. So I tried leaving it a little more polymorphic:
namespace doesntwork
data AutoM : {x : Type } -> (m : x -> Type) -> (a : Type) -> (b : Type) -> Type where
AutoMC : (a -> m (b, AutoM m a b)) -> AutoM m a b
data Identity a = IdentityC a
Auto : Type -> Type -> Type
Auto = AutoM Identity
This at least type-checks. But when I try:
const_auto : Monad m => {m : x -> Type } -> {a : Type} -> b -> AutoM m a b
const_auto b = AutoMC (\_ => return (b, const_auto b))
That, however, is no good:
When elaborating right hand side of Stream.doesntwork.const_auto:
When elaborating an application of function Prelude.Monad.return:
Can't unify
(A, B) (Type of (a, b))
with
(b, AutoM m4 a b) (Expected type)
And I can't make much sense of the type error. Why in the world would the type of (a, b) be mentioned, when a isn't used anywhere in the definition of const_auto? I have the feeling the definition of AutoM itself is already at fault, but I don't really know why or how.

You were right when your intuition told you that m being a monad, it should have type Type -> Type. The problem here is that (,) is overloaded to mean both the Pair type constructor and the mkPair data constructor and Idris' elaborator makes the wrong choice.
By picking explicitly Pair, you fix the definition:
data AutoM : (m : Type -> Type) -> (a : Type) -> (b : Type) -> Type where
AutoMC : (a -> m (Pair b (AutoM m a b))) -> AutoM m a b
Now, if you just do that you'll get another cryptic message:
Auto.idr:18:14:
When elaborating right hand side of Main.doesntwork.const_auto:
Can't resolve type class Monad m3
Metavariables: Main.doesntwork.const_auto
The problem here is the fact that you introduce an implicit m in the type annotation of const_auto which is different from the one already introduced by the constraint Monad m => and so Idris cannot find a Monad instance for this new m. The solution is to not introduce it at all (the constraint mentioning an m being enough for it to be in scope) like so:
const_auto : Monad m => {a : Type} -> b -> AutoM m a b

Related

How to build a list of heterogeneous dependant pairs in Coq

I'd like to be able to have an heterogeneous sequence of dependent pairs (T, f) where T is in Set and f if a function T -> bool such as
Definition classif :
seq (forall T : Set, T -> bool) :=
[:: (fun b : bool => b); (fun n : nat => false)].
Note: I'm using SSReflect syntax for lists.
Clearly the type written above is not the right one.
Is it possible ?
#ThéoWinterhalter's answer is the way to go here. Just add a precision w.r.t. his answer [I initially posted it as a comment but that hindered the readability of the code…]:
the type you are looking for here is {T : Set & T -> bool}, it is a Σ-type and relies on the following inductive:
Print sigT.
Inductive sigT (A : Type) (P : A -> Type) : Type :=
existT : forall x : A, P x -> {x : A & P x}
And to ease your definition of classif, you could also define a shortcut:
From mathcomp Require Import all_ssreflect.
Set Implicit Arguments.
Definition sigma (T' : Set) f := (existT (fun A : Set => A -> bool) T' f).
Definition classif :
seq {T : Set & T -> bool} :=
[:: sigma (fun b : bool => b); sigma (fun n : nat => false)].
You're looking for dependent pairs and are writing dependent functions instead.
The type of pointed types is
{ A : Set & A }
Then you can build for instance the pair of nat and 1:
Check (existT (fun A : Set => A) nat 1) : { A : Set & A }.
It is nicer with some notations but there you have it.

A Haskell List Involving Recursion and High Order Functions

Now I have this code that takes a list and does something to the first element and then to every other one. And it returns a list of the transformed elements. The problem I am having is that I want to have a list that contains the untransformed and the transformed elements. This is what I have so far:
applyToEveryOther :: (a -> b) -> [a] -> [b]
applyToEveryOther _ [] = []
applyToEveryOther f [x] = [f x]
applyToEveryOther f (x:y:xs) = f x : y : applyToEveryOther f xs
The error it is giving me says there is a problem with the : y part of the function
When I try your code, I get the following (admittedly somewhat lengthy and confusing) error message:
EveryOther.hs:4:42: error:
• Couldn't match type ‘b’ with ‘a’
‘b’ is a rigid type variable bound by
the type signature for:
applyToEveryOther :: forall a b. (a -> b) -> [a] -> [b]
at EveryOther.hs:1:22
‘a’ is a rigid type variable bound by
the type signature for:
applyToEveryOther :: forall a b. (a -> b) -> [a] -> [b]
at EveryOther.hs:1:22
Expected type: [a]
Actual type: [b]
• In the second argument of ‘(:)’, namely ‘applyToEveryOther f xs’
In the second argument of ‘(:)’, namely
‘y : applyToEveryOther f xs’
In the expression: f x : y : applyToEveryOther f xs
• Relevant bindings include
xs :: [a] (bound at EveryOther.hs:4:26)
y :: a (bound at EveryOther.hs:4:24)
x :: a (bound at EveryOther.hs:4:22)
f :: a -> b (bound at EveryOther.hs:4:19)
applyToEveryOther :: (a -> b) -> [a] -> [b]
(bound at EveryOther.hs:2:1)
However, it's worth trying to figure out what GHC is saying here. As per the second bullet point, GHC was processing the subexpression y : applyToEveryOther f xs, and specifically looking at the second argument to the : operator in that expression (namely applyToEveryOther f xs. It expected that expression to have type [a], but the actual type of the expression was type [b].
Here, a and b are both "rigid" types, meaning simply that they were specified explicitly by the programmer. GHC also notes, in the relevant bindings, that y had type a.
So, to sum up, you asked GHC to evaluate the expression:
y : applyToEveryOther f xs
where you already specified that y had type a and applyToEveryOther f xs had type [b], and GHC refused to do this because lists in Haskell can't mix two different types.
And that's kind of the key to the whole problem. You want to transform some of the elements of your [a] list from a to b, but then you want to return a mixed list of as and bs. Haskell can't do that!
The only way your function can work is if you change the signature so that a and b are the same type:
applyToEveryOther :: (a -> a) -> [a] -> [a]
and your code will work fine.
Another way you could "discover" the correct signature is to leave it out and have Haskell infer the most general possible signature. If you load the code (without the explicit signature) into GHCi and ask for the type, you get:
> :t applyToEveryOther
applyToEveryOther :: (a -> a) -> [a] -> [a]
>
which is the most general possible type for this function.
If I understood correctly you wanted both, the original and transformed values.
However evaluating applyToEveryOther (+3) [0,1,2] returns [3,1,5]. If you want [0,3,1,4,2,5] as a result, try
applyToEveryOther _ [] = []
applyToEveryOther f [x] = [x,f x]
applyToEveryOther f (x:xs) = x: f x : applyToEveryOther f xs

Modeling recursive fmap (sort of) over a list

I was wondering what the best way is to implement the following problem in a functional programming language (in this example Haskell):
You have a function (or a 'way') that turns 2 inputs, with the type a and b, in 2 ouputs of the same type (ex: Half adder). Lets call it f
in Haskell it would have this sort of type signature
a -> b -> (a, b)
And you have a list with elements of type a. (or another type of data structure).
Now if supplied with an initial b I want the following thing to happen (concept explained with recursive implementation):
Execute f with the initial b and the first element, modify the b and the element with the output of the function and repeat for the next element.
In Haskell:
exec _ [] _ = []
exec f (x:xs) b = let (x',b') = f x b in x':(exec f xs b')
What would be the best/most efficient way to model this sort of behavior.
It's mapM for the State monad.
OK, expanding a little.
Let's first enter this into ghci and see the type of the exec function:
Prelude> let {exec _ [] _ = []; exec f (x:xs) b = let (x',b') = f x b in x':(exec f xs b')}
Prelude> :t exec
exec :: (t2 -> t1 -> (t, t1)) -> [t2] -> t1 -> [t]
It's almost as you described, except that t and t2 don't have to be of the same type. That's good.
Now, another observation: we actually lose information, when we do what you describe. Specifically, we throw away the last value of b (or t, as ghci calls it). Let us preserve it for a moment; we can always throw it away later:
exec' _ [] b = ([], b)
exec' f (x:xs) b =
let (x',b') = f x b
(xs', b'') = exec' f xs b'
in (x':xs', b'')
And ghci says
Prelude> :t exec'
exec' :: (t2 -> t1 -> (t, t1)) -> [t2] -> t1 -> ([t], t1)
Than we can define
exec f xs b = fst $ exec' f xs b
But now the type of exec' contains a clear pattern. We can make it more explicit:
type S b c = b -> (c, b)
exec' :: (a -> S b c) -> [a] -> S b [c]
And now it's clear that S is almost exactly the State monad (well, it's actual definition in a modern setting is a bit more complicated, but not much: https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-State-Lazy.html#t:StateT); really, it's just a newtype:
newtype State b c = State {runState :: b -> (c, b)}
And if we generalize the type of exec' to use an arbitrary monad instead of State, we get
Monad m => (a -> m c) -> [a] -> m [c]
Of course, we can't know for sure that such a thing actually exists, since we only have an implementation for the State monad, but... it does. It's called mapM (again, it's actual definition in the modern setting is more complicated: https://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:mapM) — which makes sense, since without a monad it would be just
(a -> c) -> [a] -> [c]
and that's exactly the type of map.
Of course, you can't be sure that exec' IS mapM without examining the latter's implementation. But in Haskell it just often happens that things that have the same type, if it's reasonably generic, are one and the same.
It also makes sense that State monad would be involved somehow — after all, you DO use b as a state, changing it as you go through the list.
So, if exec' is mapM, how do we get back to exec? Well, we need to go from the monadic value State b [c] to just [c], feeding it some b. We can — again — generalize; let's say, we go from State b d to d, without mentioning the list. And again — there is a function like that, it's called evalState: https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-State-Lazy.html#v:evalState.
So, finally, we are able to produce the final result:
eval f xs b = evalState (mapM (\x -> state (\b -> f x b)) xs) b
which we can shorten to
eval f xs b = evalState (mapM (\x -> state (f x)) xs) b
or just
eval f xs = evalState (mapM (state . f) xs)
or even
eval f = evalState . mapM (state . f)
We can make it completely point-free, but that would be pointless (and contain too many points):
eval = (evalState .) . mapM . (state .)

Get function as parameter in haskell

I can't figure this, I have a type called Enumeration
> type Enumeration a = Int -> [a]
And I need to map over it. I wrote this following function:
> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f (m fa) = \n -> imapF f fa
where imapF is defined like this:
> imapF :: (a -> b) -> [a] -> [b]
> imapF _ [] = []
> imapF f (x:xs) = f x : imapF f xs
but when I try to load my code I get the following error BinaryTrees.lhs:91:14: Parse error in pattern: m regarding my imapE function.
I am trying to get the first enumeration Enumeration a as the function it is (Int and [a])
You cannot pattern match over a function, but you don't have to do that:
> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f g = (imapF f) . g
(Well, imapF is just map really).
Without using .:
> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f g = \n -> imapF f (g n)
A possible solution could be
imapE :: (a -> b) -> Enumeration a -> Enumeration b
imapE = map . map
Indeed, the above is equivalent to
imapE f = map (map f)
where
f :: a -> b
map f :: [a] -> [b]
map (map f) :: (Int -> [a]) -> (Int -> [b])
since both [] and (->) Int are functors.
The main "trick" to this kind of exercises is to think more about the types than the actual values.
This might feel a bit obscure if you're a beginner. Once you'll get more familiar with functors, however, this will become quite natural.
(People very accustomed to this style could even hint to this solution with some cryptic note "functors compose", and leaving you to figure out what's really going on. When that happens, don't give up -- eventually it will make sense ;-))

Standard Haskell function :: (a -> Maybe a) -> a -> [a]

I have a function defined
maybeToList :: (a -> Maybe a) -> a -> [a]
maybeToList f x = x : maybe [] (maybeToList f) (f x)
This function seems so obvious that I can't believe it is not standard.
Is it defined in some module (I already checked Data.Maybe)?
Your function isn't in the standard libraries because it's a specialized form of one that is:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f b =
case f b of
Just (a,new_b) -> a : unfoldr f new_b
Nothing -> []
That said, the case where the list elements are the same as the sequence of seed values is common, and it's clumsy to write in terms of just unfoldr and other standard functions, so I'm not sure why it's not in the standard libraries as well.