In the following stack script, I can't apply my strangeHeadMay
function to a NonEmpty
list, but it works fine on a regular list.
#!/usr/bin/env stack
{- stack script --nix --resolver lts-13.6 -}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# OPTIONS_GHC -Wno-partial-type-signatures #-} -- hide some scary types
import Control.Arrow ((&&&))
import Control.Monad (join)
import Data.Foldable (toList)
import Data.Function ((&))
import Data.Functor ((<&>))
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as LNE
import Data.Maybe (catMaybes)
import Data.Tuple.Sequence (sequenceT)
strangeHeadMay :: forall a t. (Semigroup (t a), _) => t a -> Maybe a
strangeHeadMay xs =
let xsWrapped :: t (t a) = pure <$> xs -- <- Contrived example
-- This is the functionality I actually need:
xsMay :: Maybe (t a) = xsWrapped & (headMay &&& tailMay) & sequenceT
<&> (\(h, t) -> foldr mappend h t)
in do
xs' <- xsMay
xs' & toList & headMay
main :: IO ()
main = do
let nexs :: NonEmpty (Maybe Double) = Nothing :| [Just (2.0)]
let xs = LNE.toList nexs
let xsHead = strangeHeadMay xs
let nexsHead = strangeHeadMay nexs
pure ()
headMay :: Foldable f => f a -> Maybe a
headMay = foldr (const . Just) Nothing
tailMay :: Foldable f => f a -> Maybe (f a)
tailMay = foldr (seq . Just) Nothing
The error is
/home/brandon/workspace/foldNEmaybes.hs:34:18: error:
• No instance for (Monoid (NonEmpty (Maybe Double)))
arising from a use of ‘strangeHeadMay’
• In the expression: strangeHeadMay nexs
In an equation for ‘nexsHead’: nexsHead = strangeHeadMay nexs
In the expression:
do let nexs :: NonEmpty (Maybe Double) = Nothing :| ...
let xs = LNE.toList nexs
let xsHead = strangeHeadMay xs
let nexsHead = strangeHeadMay nexs
....
|
34 | let nexsHead = strangeHeadMay nexs
| ^^^^^^^^^^^^^^^^^^^
Also, I must admit I'm not totally clear on why I need the partially typed signature, but changing (Semigroup (t a), _)
to (Semigroup (t a))
makes bad things happen.
Even though <>
and mappend
do the same thing, you can only use the latter if you have a Monoid
constraint, so one got added to your _
in the type signature. To fix it, use foldr (<>)
instead of foldr mappend
.
And you don't need the hole in the type signature. You can write out what goes in it and it'll still work: Applicative t
and Foldable t
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With