I'm trying to complete Exercise 5 from section 6.7 of Phil Freeman's PureScript book. The exercise wants me to write a Foldable instance for the following type.
data NonEmpty a = NonEmpty a (Array a)
I've written this instance by implementing foldMap.
instance foldableNonEmpty :: Foldable a => Foldable NonEmpty where
foldMap :: forall a m. Monoid m => (a -> m) -> NonEmpty a -> m
foldMap f (NonEmpty x xs) = (f x) <> (foldMap f xs)
foldr :: forall a b. (a -> b -> b) -> b -> NonEmpty a -> b
foldr f = foldrDefault f
foldl f = foldlDefault f
But that generates the following error.
Error found:
in module Data.Hashable
at src/Data/Hashable.purs line 110, column 11 - line 110, column 23
No type class instance was found for
Data.Foldable.Foldable t2
The instance head contains unknown type variables. Consider adding a type annotation.
while checking that type forall f a b. Foldable f => (a -> b -> b) -> b -> f a -> b
is at least as general as type (a0 -> b1 -> b1) -> b1 -> NonEmpty a0 -> b1
while checking that expression foldrDefault
has type (a0 -> b1 -> b1) -> b1 -> NonEmpty a0 -> b1
in value declaration foldableNonEmpty
where b1 is a rigid type variable
bound at line 110, column 11 - line 110, column 23
a0 is a rigid type variable
bound at line 110, column 11 - line 110, column 23
t2 is an unknown type
I think I'm getting the error because foldr = foldrDefault implies to the compiler that NonEmpty is already foldable when that's what I'm trying to instance, but then I have no idea how to use the default fold implementations. Any help would be greatly appreciated.
I don't think it's actually a problem with your use of the defaults. You seem to have added an unnecessary Foldable a constraint on your instance which I don't think you need. So your instance can be:
instance foldableNonEmpty :: Foldable NonEmpty where
Once you remove that, I think the rest is right!
I tested in the try.purescript.org editor here: http://try.purescript.org/?gist=ce6ea31715bee2b65f3da374fd39181c
Related
The functor of the identity monad can be defined as:
data Identity a = Identity a
Because this monad is free, an alternative definition is the following:
data Term f a = Pure a | Impure (f (Term f a))
data Zero a
type IdentityF a = Term Zero a
Since this is the same monad defined in two ways, they shoud be
convertible into each other. That is to say that one should be able to define two
functions f :: Identity a -> IdentityF a and g :: IdentityF a -> Identity a such that their compositions f . g and g . f are
identities. The function f is easy to define:
f :: Identity a -> IdentityF a
f (Identity a) = Pure a
But what about the function g?
g :: IdentityF a -> Identity a
g (Pure a) = Identity a
g (Impure x) = ??????
What should be the value of g (Impure x). I could try to cheat and say it
is undefined but then f . g would not be the identity function and
Identity and IdentityF would not be isomorphic.
One suitable definition is:
g (Impure x) = case x of
There are no branches in the case. This was not a typo. There are exactly as many branches in the case as there are constructors in Zero a, as required; this is a complete pattern match.
(You must turn on the EmptyCase extension for GHC to accept this as-is.)
I have not found a function in Scala or Haskell that can transform/map both Either's Left and Right cases taking two transformation functions at the same time, namely a function that is of the type
(A => C, B => D) => Either[C, D]
for Either[A, B] in Scala, or the type
(a -> c, b -> d) -> Either a b -> Either c d
in Haskell. In Scala, it would be equivalent to calling fold like this:
def mapLeftOrRight[A, B, C, D](e: Either[A, B], fa: A => C, fb: B => D): Either[C, D] =
e.fold(a => Left(fa(a)), b => Right(fb(b)))
Or in Haskell, it would be equivalent to calling either like this:
mapLeftOrRight :: (a -> c) -> (b -> d) -> Either a b -> Either c d
mapLeftOrRight fa fb = either (Left . fa) (Right . fb)
Does a function like this exist in the library? If not, I think something like this is quite practical, why do the language designers choose not to put it there?
Don't know about Scala, but Haskell has a search engine for type signatures. It doesn't give results for the one you wrote, but that's just because you take a tuple argument while Haskell functions are by convention curried†. https://hoogle.haskell.org/?hoogle=(a -> c) -> (b -> d) -> Either a b -> Either c d does give matches, the most obvious being:
mapBoth :: (a -> c) -> (b -> d) -> Either a b -> Either c d
...actually, even Google finds that, because the type variables happen to be exactly as you thought. (Hoogle also finds it if you write it (x -> y) -> (p -> q) -> Either x p -> Either y q.)
But actually, as Martijn said, this behaviour for Either is only a special case of a bifunctor, and indeed Hoogle also gives you the more general form, which is defined in the base library:
bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
†TBH I'm a bit disappointed that Hoogle doesn't by itself figure out to curry the signature or to swap arguments. Pretty sure it actually used to do that automatically, but at some point they simplified the algorithm because with the huge number of libraries the time it took and number of results got out of hand.
Cats provides Bifunctor, for example
import cats.implicits._
val e: Either[String, Int] = Right(41)
e.bimap(e => s"boom: $e", v => 1 + v)
// res0: Either[String,Int] = Right(42)
The behaviour you are talking about is a bifunctor behaviour, and would commonly be called bimap. In Haskell, a bifunctor for either is available: https://hackage.haskell.org/package/bifunctors-5/docs/Data-Bifunctor.html
Apart from the fold you show, another implementation in scala would be either.map(fb).left.map(fa)
There isn't such a method in the scala stdlib, probably because it wasn't found useful or fundamental enough. I can somewhat relate to that: mapping both sides in one operation instead of mapping each side individually doesn't come across as fundamental or useful enough to warrant inclusion in the scala stdlib to me either. The bifunctor is available in Cats though.
In Haskell, the method exists on Either as mapBoth and BiFunctor is in base.
In Haskell, you can use Control.Arrow.(+++), which works on any ArrowChoice:
(+++) :: (ArrowChoice arr) => arr a b -> arr c d -> arr (Either a c) (Either b d)
infixr 2 +++
Specialised to the function arrow arr ~ (->), that is:
(+++) :: (a -> b) -> (c -> d) -> Either a c -> Either b d
Hoogle won’t find +++ if you search for the type specialised to functions, but you can find generalised operators like this by replacing -> in the signature you want with a type variable: x a c -> x b d -> x (Either a b) (Either c d).
An example of usage:
renderResults
:: FilePath
-> Int
-> Int
-> [Either String Int]
-> [Either String String]
renderResults file line column
= fmap ((prefix ++) +++ show)
where
prefix = concat [file, ":", show line, ":", show column, ": error: "]
renderResults "test" 12 34 [Right 1, Left "beans", Right 2, Left "bears"]
==
[ Right "1"
, Left "test:12:34: error: beans"
, Right "2"
, Left "test:12:34: error: bears"
]
There is also the related operator Control.Arrow.(|||) which does not tag the result with Either:
(|||) :: arr a c -> a b c -> arr (Either a b) c
infixr 2 |||
Specialised to (->):
(|||) :: (a -> c) -> (b -> c) -> Either a b -> c
Example:
assertRights :: [Either String a] -> [a]
assertRights = fmap (error ||| id)
sum $ assertRights [Right 1, Right 2]
==
3
sum $ assertRights [Right 1, Left "oh no"]
==
error "oh no"
(|||) is a generalisation of the either function in the Haskell Prelude for matching on Eithers. It’s used in the desugaring of if and case in arrow proc notation.
Is there any way to do something like
first = {x:0}
second = {x:1,y:1}
both = [first, second]
such that both is inferred as {x::Int | r} or something like that?
I've tried a few things:
[{x:3}] :: Array(forall r. {x::Int|r}) -- nope
test = Nil :: List(forall r. {x::Int|r})
{x:1} : test -- nope
type X r = {x::Int | r}
test = Nil :: List(X) -- nope
test = Nil :: List(X())
{x:1} : test
{x:1, y:1} : test -- nope
Everything I can think of seems to tell me that combining records like this into a collection is not supported. Kind of like, a function can be polymorphic but a list cannot. Is that the correct interpretation? It reminds me a bit of the F# "value restriction" problem, though I thought that was just because of CLR restrictions whereas JS should not have that issue. But maybe it's unrelated.
Is there any way to declare the list/array to support this?
What you're looking for is "existential types", and PureScript just doesn't support those at the syntax level the way Haskell does. But you can roll your own :-)
One way to go is "data abstraction" - i.e. encode the data in terms of operations you'll want to perform on it. For example, let's say you'll want to get the value of x out of them at some point. In that case, make an array of these:
type RecordRep = Unit -> Int
toRecordRep :: forall r. { x :: Int | r } -> RecordRep
toRecordRep {x} _ = x
-- Construct the array using `toRecordRep`
test :: Array RecordRep
test = [ toRecordRep {x:1}, toRecordRep {x:1, y:1} ]
-- Later use the operation
allTheXs :: Array Int
allTheXs = test <#> \r -> r unit
If you have multiple such operations, you can always make a record of them:
type RecordRep =
{ getX :: Unit -> Int
, show :: Unit -> String
, toJavaScript :: Unit -> Foreign.Object
}
toRecordRep r =
{ getX: const r.x
, show: const $ show r.x
, toJavaScript: const $ unsafeCoerce r
}
(note the Unit arguments in every function - they're there for the laziness, assuming each operation could be expensive)
But if you really need the type machinery, you can do what I call "poor man's existential type". If you look closely, existential types are nothing more than "deferred" type checks - deferred to the point where you'll need to see the type. And what's a mechanism to defer something in an ML language? That's right - a function! :-)
newtype RecordRep = RecordRep (forall a. (forall r. {x::Int|r} -> a) -> a)
toRecordRep :: forall r. {x::Int|r} -> RecordRep
toRecordRep r = RecordRep \f -> f r
test :: Array RecordRep
test = [toRecordRep {x:1}, toRecordRep {x:1, y:1}]
allTheXs = test <#> \(RecordRep r) -> r _.x
The way this works is that RecordRep wraps a function, which takes another function, which is polymorphic in r - that is, if you're looking at a RecordRep, you must be prepared to give it a function that can work with any r. toRecordRep wraps the record in such a way that its precise type is not visible on the outside, but it will be used to instantiate the generic function, which you will eventually provide. In my example such function is _.x.
Note, however, that herein lies the problem: the row r is literally not known when you get to work with an element of the array, so you can't do anything with it. Like, at all. All you can do is get the x field, because its existence is hardcoded in the signatures, but besides the x - you just don't know. And that's by design: if you want to put anything into the array, you must be prepared to get anything out of it.
Now, if you do want to do something with the values after all, you'll have to explain that by constraining r, for example:
newtype RecordRep = RecordRep (forall a. (forall r. Show {x::Int|r} => {x::Int|r} -> a) -> a)
toRecordRep :: forall r. Show {x::Int|r} => {x::Int|r} -> RecordRep
toRecordRep r = RecordRep \f -> f r
test :: Array RecordRep
test = [toRecordRep {x:1}, toRecordRep {x:1, y:1}]
showAll = test <#> \(RecordRep r) -> r show
Passing the show function like this works, because we have constrained the row r in such a way that Show {x::Int|r} must exist, and therefore, applying show to {x::Int|r} must work. Repeat for your own type classes as needed.
And here's the interesting part: since type classes are implemented as dictionaries of functions, the two options described above are actually equivalent - in both cases you end up passing around a dictionary of functions, only in the first case it's explicit, but in the second case the compiler does it for you.
Incidentally, this is how Haskell language support for this works as well.
Folloing #FyodorSoikin answer based on "existential types" and what we can find in purescript-exists we can provide yet another solution.
Finally we will be able to build an Array of records which will be "isomorphic" to:
exists tail. Array { x :: Int | tail }
Let's start with type constructor which can be used to existentially quantify over a row type (type of kind #Type). We are not able to use Exists from purescript-exists here because PureScript has no kind polymorphism and original Exists is parameterized over Type.
newtype Exists f = Exists (forall a. f (a :: #Type))
We can follow and reimplement (<Ctrl-c><Ctrl-v> ;-)) definitions from Data.Exists and build a set of tools to work with such Exists values:
module Main where
import Prelude
import Unsafe.Coerce (unsafeCoerce)
import Data.Newtype (class Newtype, unwrap)
newtype Exists f = Exists (forall a. f (a :: #Type))
mkExists :: forall f a. f a -> Exists f
mkExists r = Exists (unsafeCoerce r :: forall a. f a)
runExists :: forall b f. (forall a. f a -> b) -> Exists f -> b
runExists g (Exists f) = g f
Using them we get the ability to build an Array of Records with "any" tail but we have to wrap any such a record type in a newtype before:
newtype R t = R { x :: Int | t }
derive instance newtypeRec :: Newtype (R t) _
Now we can build an Array using mkExists:
arr :: Array (Exists R)
arr = [ mkExists (R { x: 8, y : "test"}), mkExists (R { x: 9, z: 10}) ]
and process values using runExists:
x :: Array [ Int ]
x = map (runExists (unwrap >>> _.x)) arr
In the REPL this works:
> mm n = (\n -> n * 2) <$> n
> mm (2:3:Nil)
(4 : 6 : Nil)
in a file this compiles and I can run it:
squareOf ls =
map (\n -> n * n) ls
however when I add a type definition to that function
squareOf :: List Int -> Int
squareOf ls =
map (\n -> n * n) ls
I get an error:
Could not match type
List Int
with type
Int
while checking that type t0 t1
is at least as general as type Int
while checking that expression (map (\n ->
(...) n
)
)
ls
has type Int
in value declaration squareOf
where t0 is an unknown type
t1 is an unknown type
I tried changing the signature to a type alias of the list, and also I tried a forall definition with no luck.
If I inspect the definition created when I don't put signatures in my function I get:
forall t2 t3. Functor t2 => Semiring t3 => t2 t3 -> t2 t3
Can anyone explain why my signature is incorrect and also why am I getting this signature for the function?
Cheers
Edit: Thanks for the comments, updating the fn definition so it returns a List Int as well, and , of course it solves the problem
Assuming you're repl function is the behaviour you're after, you've missed out the map operator (<$>) in your later definitions.
Your repl function (with variables renamed for clarity) has the type:
mm :: forall f. Functor f => f Int -> f Int
mm ns = (\n -> n * 2) <$> ns
Which is to say: mm maps "times two" to something that is mappable" (i.e. a Functor)
Aside: you could be more concise/clear in your definition here:
mm :: forall f. Functor f => f Int -> f Int
mm = map (_*2)
This is similar to your squareOf definition, only now you're squaring so your use of (*) is more general:
squareOf :: forall f. Functor f => Semiring n => f n -> f n
squareOf = map \n -> n * n
Because (*) is a member of the Semiring typeclass.
But the signature you gave it suggests you're after some kind of fold? Let me know what output you expect from your squareOf function and I'll update the answer accordingly.
Here is map:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
Narrowing to List Int and Int -> Int, the compiler infers
map :: (Int -> Int) -> List Int -> List Int
So, in squareOf, the expression reduces to a list of integers, not an integer. That is why the compiler complains.
In the process of writing a simple RPN calculator, I have the following type aliases:
type Stack = List[Double]
type Operation = Stack => Option[Stack]
... and I have written a curious-looking line of Scala code:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
This takes an initial stack of values and applies a list of operations to that stack. Each operation may fail (i.e. yields an Option[Stack]) so I sequence them with flatMap. The thing that's somewhat unusual about this (in my mind) is that I'm folding over a list of monadic functions, rather than folding over a list of data.
I want to know if there's a standard function that captures this "fold-bind" behavior. When I'm trying to play the "Name That Combinator" game, Hoogle is usually my friend, so I tried the same mental exercise in Haskell:
foldl (>>=) (Just stack) operations
The types here are:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
So the type of my mystery foldl (>>=) combinator, after making the types of foldl and (>>=) line up, should be:
mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a
... which is again what we'd expect. My problem is that searching Hoogle for a function with that type yields no results. I tried a couple other permutations that I thought might be reasonable: a -> [a -> m a] -> m a (i.e. starting with a non-monadic value), [a -> m a] -> m a -> m a (i.e. with arguments flipped), but no luck there either. So my question is, does anybody know a standard name for my mystery "fold-bind" combinator?
a -> m a is just a Kleisli arrow with the argument and result types both being a. Control.Monad.(>=>) composes two Kleisli arrows:
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
Think flip (.), but for Kleisli arrows instead of functions.
So we can split this combinator into two parts, the composition and the "application":
composeParts :: (Monad m) => [a -> m a] -> a -> m a
composeParts = foldr (>=>) return
mysteryCombinator :: (Monad m) => m a -> [a -> m a] -> m a
mysteryCombinator m fs = m >>= composeParts fs
Now, (>=>) and flip (.) are related in a deeper sense than just being analogous; both the function arrow, (->), and the data type wrapping a Kleisli arrow, Kleisli, are instances of Control.Category.Category. So if we were to import that module, we could in fact rewrite composeParts as:
composeParts :: (Category cat) => [cat a a] -> cat a a
composeParts = foldr (>>>) id
(>>>) (defined in Control.Category) is just a nicer way of writing as flip (.).
So, there's no standard name that I know of, but it's just a generalisation of composing a list of functions. There's an Endo a type in the standard library that wraps a -> a and has a Monoid instance where mempty is id and mappend is (.); we can generalise this to any Category:
newtype Endo cat a = Endo { appEndo :: cat a a }
instance (Category cat) => Monoid (Endo cat a) where
mempty = Endo id
mappend (Endo f) (Endo g) = Endo (f . g)
We can then implement composeParts as:
composeParts = appEndo . mconcat . map Endo . reverse
which is just mconcat . reverse with some wrapping. However, we can avoid the reverse, which is there because the instance uses (.) rather than (>>>), by using the Dual a Monoid, which just transforms a monoid into one with a flipped mappend:
composeParts :: (Category cat) => [cat a a] -> cat a a
composeParts = appEndo . getDual . mconcat . map (Dual . Endo)
This demonstrates that composeParts is a "well-defined pattern" in some sense :)
The one starting with a non-monadic value is (modulo flip)
Prelude> :t foldr (Control.Monad.>=>) return
foldr (Control.Monad.>=>) return
:: Monad m => [c -> m c] -> c -> m c
(or foldl)
(Yes, I know this doesn't answer the question, but the code layout in comments isn't satisfactory.)