For that newtype is treated as a whole different type in the type system, I'm wondering if there is any way to use pattern matching or iterate a list with newtype, as follow.
newtype Foo = Foo [Int]
bar :: Foo -> Int
bar (x : xs) = x bar xs
bar [] = 0
CodePudding user response:
There are multiple options.
Just manually wrap/unwrap the newtype right in place.
bar (Foo (x : xs)) = x bar (Foo xs) bar (Foo []) = 0Implement the function on lists, and unwrap it once before passing to the function. In this case the list version is just
sum, so we can usebar (Foo xs) = sum xsMake an interface that allows to manipulate
Foovalues as if they were lists.{-# LANGUAGE PatternSynonyms #-} {-# COMPLETE (:%), FooNil #-} pattern (:%) :: Int -> Foo -> Foo pattern x :% xs <- Foo (x : (Foo -> xs)) where x :% xs = Foo (x : getFoo xs) pattern FooNil :: Foo pattern FooNil = Foo [] bar :: Foo -> Int bar (x :% xs) = x bar xs bar FooNil = 0Abstract. You don't really need the particular list deconstructors, you just need some way to implement a fold over the contained data. There is a standard
Foldableclass inbasefor just this, but it would require you container to be parametric over the contained type. Since it's not parametric, you need to useMonoFoldableclass from themono-traversablepackage instead.import Data.MonoTraversable type instance Element Foo = Int import MonoFoldable Foo where ofoldr f (Foo (x:xs)) e = f x $ ofoldr f (Foo xs) e ofoldr _ (Foo []) e = e bar = ofoldr ( ) 0
Note that generally, this sort of function should be implemented with a strict left fold instead of a right fold.
