Haskell Concat-Typeclass - haskell

I wondered if there is a defined typeclass in Haskell, which declares concatenation.
For lists there is ++ and concat. But of course there are other types which are concatable.
Example:
type Valuater = A -> [Int]
concatValuater :: [Valuater] -> Valuater
concatValuater vs = \a -> concat [v a | v <- vs]
Isn't there a typeclass for concat?

Most likely you'd like to take a look at Monoid
class Monoid a where
mempty :: a
mappend :: a -> a -> a
mconcat :: [a] -> a

As #JAbrahamson has said, Monoid is precisely the type class you're looking for. For your case, you'd be able to implement it like this:
newtype Valuater = Valuater {
evalValuater :: A -> [Int]
}
instance Monoid Valuater where
mempty = Valuater (const [])
mappend (Valuater f) (Valuater g) = Valuater (\a -> f a ++ g a)
mconcat vs = Valuater (\a -> concatMap (`evalValuater` a) vs)
Then you can use all the Monoid related functions on Valuaters.
In fact, you can make this a bit more general:
newtype Valuater' m = Valuater {
evalValuater :: A -> m
}
instance Monoid m => Monoid (Valuater' m) where
mempty = Valuater (const mempty)
mappend (Valuater f) (Valuater g) = Valuater (\a -> f a <> g a)
mconcat vs = Valuater (\a -> mconcat $ map (`evalValuater` a) vs)
type Valuater = Valuater' [Int]
And now you can have a Valuater' work across different monoids very easily, but I don't know if this is particularly useful for approaching your specific problem.

Related

Is there a standard combinator packing the result of a lens in functor?

While trying to apply a function with multiple layers of functors to a member of a host data structure, as in the following example:
update ::
(SomeProductField -> Maybe (Int, SomeProductField)) ->
(SomeProduct -> Maybe (Int, SomeProduct))
I came up with the following utility:
inFunctor :: Functor f => Lens s t a b -> Lens s (f t) a (f b)
inFunctor lens f = getCompose . lens (Compose . f)
Allowing me to implement the update function like this:
someProductFieldLens :: Lens' SomeProduct SomeProductField
update = inFunctor someProductFieldLens
I am wondering whether something like this is already present in "lens" and whether the same is achievable somehow otherwise using the existing means.
Not much of a standard approach, perhaps, but anyway: alaf can handle the Compose wrapping. For instance:
data SomeProduct = SomeProduct
{ _someProductField :: Bool
, _anotherProductField :: String
}
deriving Show
makeLenses ''SomeProduct
ghci> alaf Compose someProductField (\b -> Just (fromEnum b, not b)) (SomeProduct False "foo")
Just (0,SomeProduct {_someProductField = True, _anotherProductField = "foo"})
If you'd still like to define the general combinator:
inFunctor :: Functor f => Lens s t a b -> Lens s (f t) a (f b)
inFunctor l = alaf Compose l

How do I write Foldable instance for this type?

I have the following data type defined:
data SynthesisTreeResult comp a = CompNode (comp a) [SynthesisTreeResult comp a]
| InputLeaf Location
I want to be able to turn it into a list of type [comp a] using toList, which requires an instance of Foldable.
I tried to write an instance by implementing foldMap:
class Foldable f where
foldMap :: Monoid m => (a -> m) -> f a -> m
However, since comp :: * -> *, I have to write instance Foldable (SynthesisTreeResult comp) where ..., which causes foldMap to have following type
foldMap :: Monoid m => (a -> m) -> SynthesisTreeResult comp a -> m
But I need
foldMap :: Monoid m => (comp a -> m) -> SynthesisTreeResult comp a -> m
to be able to fold it.
Is it possible? Maybe I need to impose Functor on comp?
Thanks to #Willem Van Onsem hint, I figured out the proper instance:
instance Foldable comp => Foldable (SynthesisTreeResult comp) where
foldMap f (CompNode comp children) = mappend (foldMap f comp) $ mconcat $ map (foldMap f) children
Given your comment that you want a comp a instead of an a, you need to make a minor change to your type:
data SynthesisTreeResult t = CompNode t [SynthesisTreeResult t]
| InputLeaf Location
That's necessary because the type that comes out of foldMap is always the last type parameter of the type that went in. Fixing the usages of your type is easy; just change SynthesisTreeResult Foo Bar to SynthesisTreeResult (Foo Bar) everywhere. With that change, here's your Foldable instance:
instance Foldable SynthesisTreeResult where
foldMap f (CompNode x xs) = f x <> foldMap (foldMap f) xs
foldMap _ (InputLeaf _) = mempty
If that change to your type isn't acceptable, then you can't use Foldable to get what you want, and you need to write your own toList method, which you could do like this:
myToList :: SynthesisTreeResult comp a -> [comp a]
myToList (CompNode x xs) = x:concatMap myToList xs
myToList (InputLeaf _) = []

How to eliminate the boilerplate of wrapping and unwrapping using lenses

tl;dr: is it possible to use any of the lens family of abstractions to wrap/unwrap any arbitrary newtype (that provides an instance for such abstractions)?
I'll motivate my question by a simple example, based on a true story. Suppose I define the following newtype:
newtype FreeMonoid a = FreeMonoid { asMap :: Map a Int }
which is used to represent terms of the form:
a0 <> a1 <> ... <> an-1
We can represent free-monoids as lists:
instance Ord a => IsList (FreeMonoid a) where
type Item (FreeMonoid a) = a
fromList xs = FreeMonoid $ Map.fromListWith (+) $ zip xs (repeat 1)
toList (FreeMonoid p) = do
(x, n) <- Map.toList p
genericReplicate n x
Two examples of free-monoids are sequences of sum and sequences of products:
type FreeSum a = FreeMonoid (Sum a)
type FreeProduct a = FreeMonoid (Product a)
Where Sum and Product are defined in Data.Monoid. Now we could define fromList and toList operations for FreeSum and
FreeProduct as follows:
fromListSum :: Ord a => [a] -> FreeSum a
fromListSum = fromList . (Sum <$>)
fromListProduct :: Ord a => [a] -> FreeProduct a
fromListProduct = fromList . (Product <$>)
But this has quite a lot of boilerplate. It'd be nicer if we could simply say:
fromListW :: (Ord a, Wrapper f) => [a] -> FreeMonoid (f a)
fromListW = fromList . (wrap <$>)
where wrap is some operation of the (hypotetical) Wrapper class were:
wrap :: a -> f a
unwrap :: f a -> a
Similarly, I'd like to be able to write a function:
toListW :: (Ord a, Wrapper f) => FreeMonoid (f a) -> [a]
toListW = (unwrap <$>) . toList
Lenses seem to provide such an abstraction in Control.Lens.Wrapped (for which Sum and Product in this example are instances of the typeclasses there!). However my attempts to understand and use the abstractions in this module have failed. For instance:
fromListW :: (Ord a, Wrapped (f a)) => [a] -> FreeMonoid (f a)
fromListW = fromList . (Wrapped <$>)
won't work since the argument is not a list of Unwrapped (f a).
So my question is:
Do lenses provide an abstraction similar to this Wrapper class?
If not, can this "scrap-your-boilerplate" problem be solved by using lenses?
The "problem" is that you're using Wrapped, which is really meant to be a convenience pattern synonym and not a wrapping "constructor". Because it's designed to support polymorphic wrapping, you need to assert that your type can be rewrapped:
fromListW :: (Rewrapped a a, Ord a) => [Unwrapped a] -> FreeMonoid a
fromListW = fromList . (Wrapped <$>)
This then works as expected:
> let x = [1,2,3]
> fromListW x :: FreeMonoid (Sum Int)
FreeMonoid {asMap = fromList [(Sum {getSum = 1},...
> fromListW x :: FreeMonoid (Product Int)
FreeMonoid {asMap = fromList [(Product {getProduct = 1},...
>
I think a more idiomatic lens implementation would be:
fromListW :: (Rewrapped a a, Ord a) => [Unwrapped a] -> FreeMonoid a
fromListW = fromList . view (mapping _Unwrapped)
This still requires the Rewrapped a a constraint, but you can use the non-polymorphic _Unwrapped' instead:
fromListW :: (Wrapped a, Ord a) => [Unwrapped a] -> FreeMonoid a
fromListW = fromList . view (mapping _Unwrapped')
which looks a little more natural.
The toListW implementation would have similar structure:
toListW :: (Wrapped a, Ord a) => FreeMonoid a -> [Unwrapped a]
toListW = view (mapping _Wrapped') . toList

Writing a foldMap in Haskell

I am trying to write my own foldMap function as an excersice to learn Haskell
Currently it looks like this
class Functor f => Foldable f where
fold :: Monoid m => f m -> m
foldMap :: Monoid m => (a -> m) -> f a -> m
foldMap g a = fold (<>) mempty (fmap g a)
However when compiling it it gives the following error
Could not deduce (Monoid ((f m -> m) -> fm -> m)) arising from use of 'fold'
from the context (Foldable f) bound by the class declaration for 'Foldable' at (file location)
or from (Monoid m) bound by the type signature for foldMap :: Monoid m => (a -> m) -> f a -> m at (file location
In the expression fold (<>) mempty (fmap g a)
In an equation for 'foldMap':
foldMap g a = fold (<>) mempty (fmap g a)
I can't figure out what the compiler is trying to tell me with this error, can anyone tell me what goes wrong with my foldMap?
Maybe we should do an answer with the actual solution:
I hope it's now clear, that this is a possible definition:
class Functor f => Foldable f where
fold :: Monoid m => f m -> m
foldMap :: Monoid m => (a -> m) -> f a -> m
foldMap g a = fold $ fmap g a
follow the types
Andrew and Lee already gave you a high level explanation but maybe I can give you another view on it:
Let's just follow the types to oget to this answer:
We want a function f a -> m where m is a monoid and f is a functor. In addition we have a function g :: a -> m we can use to get from some a into the monoid - nice.
Now we get some additional functions:
fold :: f m -> m from our own class
fmap :: (a -> b) -> f a -> f b from the Functor f
Ok we need f a -> m now if only the a would be an m then we could use fold ... dang.
But wait: we can make a a into a m using g- but the a is packed into f ... dang.
Oh wait: we can make a f a into a f m using fmap .... ding-ding-ding
So let's do it:
make f a into f m: fmap g a
use fold on it: fold (fmap g a)
or using $:
foldMap g a = fold $ fmap g a
example
Let's get something so we can try:
module Foldable where
import Data.Monoid
class Functor f => Foldable f where
fold :: Monoid m => f m -> m
foldMap :: Monoid m => (a -> m) -> f a -> m
foldMap g a = fold $ fmap g a
instance Foldable [] where
fold [] = mempty
fold (x:xs) = mappend x (fold xs)
here is a simple example using this with Sum and [1..4]:
λ> foldMap Sum [1..4]
Sum {getSum = 10}
which seems fine to me.
A Monoid has two functions, mappend and mempty, and you can use (<>) in place of mappend.
Typeclasses work because the compiler inserts the appropriate definition for the function depending on the types of the data, so (happily) there's no need to pass around the function in question.
The mistake you've made is to unnecessarily pass the Monoid functions you're using in.
For example, if I defined a function to test if something was in a list like this:
isin :: Eq a => a -> [a] -> Bool
isin equalityFunction a list = any (equalityFunction a) list
I'd have unnecessarily tried to pass the equalityFunction as an argument, and the type signature doesn't match it.
Instead I should define
isin :: Eq a => a -> [a] -> Bool
isin a list = any (== a) list
using the standard name for the equality function as defined in the Eq typeclass.
Similarly, you neither need nor should pass the (<>) or empty arguments.

Extracting `a` from Applicative `f a`

Learn You a Haskell offers the following exercise:
Let's try implementing a function that takes a list of applicatives and
returns an applicative that has a list as its result value.
LYAH gives the type signature sequenceA' :: (Applicative f) => [f a] -> f [a]
I started with Applicative, but wasn't sure how to extract a from f a in a general way for all Applicative's.
So, I implemented it as a Maybe. Of course this is unacceptable for all `Applicative's.
import Control.Applicative
sequenceA' :: (Num a) => [Maybe a] -> Maybe [a]
sequenceA' [] = pure []
sequenceA' xs = pure $ [extract' x | x <- xs ]
extract' :: (Num a) => Maybe a -> a
extract' x = case x of
Just y -> y
Nothing -> 0
How can I extract a from f a where f is an Applicative?
You can't in general. In fact, the Maybe example you gave is a good example of why since it requires it to be a Num instance. It wouldn't make sense for the Maybe Applicative in general, so that would be a counterexample to a general solution. Another counterexample would be IO. There is no valid extract implementation for IO.
To make a function that is general enough to work with all Applicative instances, you must be able to construct the function using only methods from Applicative and its super-class, Functor. There is no way to make extract using only fmap, pure and (<*>).
It's not necessary to take things out of the applicative functor to achieve this.
The great thing about applicative functors is they allow you to use ordinary functions on the results of each applicative computation, so
if you have applicatives c1, c2 and c3 of types f a, f b, f c
that produce values v1, v2 and v3 of types a, b and c,
but you actually want to use a function g :: a -> b -> c -> d on the values
to produce g v1 v2 v3 :: d, then you can do
g <$> c1 <*> c2 <*> c3
which has type f d.
So we can use the function (:) to join the first value out of our list of applicatives with the rest of them, so you can do someytthing like (:) <$> thingThatGivesFirstValue <*> thing that gives the rest of the list. So it'll be a nice recursion if you pattern match on the list of applicatives.
sequenceA' :: (Applicative f) => [f a] -> f [a]
sequenceA' [] = -- just give the empty list
sequenceA' (c:cs) = -- hmm. What could go here then?
so for example you should get
ghci> sequenceA' [getLine, getLine, getLine]
Hello
there
everyone
["Hello","there","everyone"]
ghci> sequenceA' [Just 3, Just 4, Just 5]
Just [3,4,5]
Here's an example function to help you along with the recursice case:
nth :: Applicative f => f Int -> f [a] -> f a
nth wrappedInt wrappedList = (!!) <$> wrappedInt <*> wrappedList
So you don't need to unwrap anything or get values out, the operators<$> and <*> let you do what you like inside.
nth (Just 3) (Just "Hello") == 'l'
Here's a hint:
foo :: Applicative f => f Int -> f Int -> f Int
foo fx fy = (+) <$> fx <*> fy -- apply + "under" the functor
bar :: Applicative f => f a -> f [a] -> f [a]
bar fx fxs = ??? <$> fx <*> fxs -- apply ??? "under" the functor
sequenceA' :: Applicative f => [f a] -> f [a]
sequenceA' [] = pure [] -- as in your solution
sequenceA' (x:xs) = let y = x -- :: f a
ys = sequenceA' xs -- :: f [a]
in ???
I use let in the last function to clarify the types which are involved. After you fill in the ??? you can of course remove the let.
You can extract a from f a with pattern matching or evaluation, if f is not IO
import Control.Applicative
import System.IO
import Control.Monad.ST
-- with AndrewC sequenceA' definition
sequenceA' :: (Applicative f) => [f a] -> f [a]
sequenceA' [] = pure []
sequenceA' (c:cs) = (:) <$> c <*> sequenceA' cs
seqOfMaybes :: [Maybe a] -> [a]
seqOfMaybes listOfMb = case sequenceA' listOfMb of
Nothing -> []
Just list -> list
-- sequencing ST computations
compute :: a -> ST s a
compute x = return x
seqOfSTData :: [Int] -> [Int]
seqOfSTData vals = runST $ (sequenceA' (map compute vals) :: ST s [Int])
-- but you cannot escape the applicative f if f is IO
readAnInt :: IO Int
readAnInt = putStrLn "give me an Int>" >> hFlush stdout >> getLine >>= (return . read)
seqOfIO :: [IO a] -> IO [a]
seqOfIO listOfIO = sequenceA' listOfIO
main :: IO ()
main = do
print $ seqOfMaybes [Just 3, Just 4, Just 5]
print $ seqOfSTData [1,2,3]
seqOfIO [readAnInt, readAnInt] >>= print

Resources