Maybe type filtered to remove Nothing

i had filtered a [Maybe Text] type to remove Nothing from the list and now i want to put the result in a [Text] type but the compiler complains about the incompatible type : (bd_rows_WDS :: [Only (Maybe Text)]) <- query conn qry_head_WDS (Only (name::String)) -- remove the records having N°BD NULL let fltWDS :: [Only Text] = Prelude.filter (\(Only a) -> case a of Nothing -> False Just a -> True) bd_rows_WDS Prelude> :load UpdateSidonie [1 of 1] Compiling Main ( UpdateSidonie.hs, interpreted ) UpdateSidonie.hs:282:33: error: • Couldn't match type ‘Maybe Text’ with ‘Text’ Expected type: [Only Text] Actual type: [Only (Maybe Text)] • In the expression: Prelude.filter (\ (Only a) -> case a of Nothing -> False Just a -> True) bd_rows_WDS In a pattern binding: fltWDS :: [Only Text] = Prelude.filter (\ (Only a) -> case a of Nothing -> False Just a -> True) bd_rows_WDS In the expression: do conn <- connect defaultConnectInfo {connectHost = "moita", connectUser = "mattei", connectPassword = "sidonie2", connectDatabase = "sidonie"} (rows :: [(Text, Double)]) <- query_ conn "SELECT Nom,distance FROM AngularDistance WHERE distance > 0.000278" (names :: [Only Text]) <- query_ conn "SELECT Nom FROM AngularDistance WHERE distance > 0.000278" let resLstNames = Prelude.map fromOnly names .... | 282 | let fltWDS :: [Only Text] = Prelude.filter (\(Only a) -> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^... Failed, no modules loaded. how can id do the type conversion,now i'm sure there is no more Nothing values?

On 02/01/2019 13:45, Damien Mattei wrote:
i had filtered a [Maybe Text] type to remove Nothing from the list and now i want to put the result in a [Text] type but the compiler complains about the incompatible type :
As you've seen, filter removes values but doesn't change the type. If you did have [Maybe Text] you could use the library function catMaybes :: [Maybe a] -> [a] to both do the filtering and change the types.
(bd_rows_WDS :: [Only (Maybe Text)]) <- query conn qry_head_WDS (Only (name::String))
-- remove the records having N°BD NULL let fltWDS :: [Only Text] = Prelude.filter (\(Only a) -> case a of Nothing -> False Just a -> True) bd_rows_WDS
But in your case you actually have [Only (Maybe Text)] rather than [Maybe Text] so catMaybes won't work. One option is to use a list comprehension instead: let fltWDS = [Only a | Only (Just a) <- bd_rows_WDS] Cheers, Ganesh

On 2019-01-03 12:43 AM, Ganesh Sittampalam wrote:
If you did have [Maybe Text] you could use the library function
catMaybes :: [Maybe a] -> [a]
to both do the filtering and change the types.
...
But in your case you actually have [Only (Maybe Text)] rather than [Maybe Text] so catMaybes won't work. One option is to use a list comprehension instead:
let fltWDS = [Only a | Only (Just a) <- bd_rows_WDS]
It probably would be helpful to remove the Only wrapper at this stage, so this might be even better: let fltWDS = [a | Only (Just a) <- bd_rows_WDS] The way to do it with catMaybes would be to map with fromOnly first: let fltWDS = catMaybes (map fromOnly bd_rows_WDS) As Ganesh shows, there's no need for a type annotation after you've done the query, because the compiler can infer the type [Text] from the types of the functions that are used. The annotations are necessary with query only because it's polymorphic and can work with a wide variety of types.

yes both works, code looks like this now: -- remove the records having N°BD NULL let fltWDS = Prelude.filter (\(Only a) -> case a of Nothing -> False Just a -> True) bd_rows_WDS -- let fltWDS = [a | Only (Just a) <- bd_rows_WDS] -- let fltWDS = catMaybes (Prelude.map fromOnly bd_rows_WDS) putStr "bd_rows_WDS filtered fltWDS =" putStrLn $ show fltWDS let lg_fltWDS = Prelude.length fltWDS putStrLn ("lg_fltWDS = " ++ (show lg_fltWDS)) let resBDtxt = if lg_fltWDS == 0 then Nothing else if lg_fltWDS == 1 then --Just (Prelude.head fltWDS) fromOnly (Prelude.head fltWDS) else --trace "WARNING: multiple BD in WDS result" (Just (Prelude.head fltWDS)) trace "WARNING: multiple BD in WDS result" fromOnly (Prelude.head fltWDS) putStr "resBDtxt =" putStrLn (maybe "Empty List" show resBDtxt) i will keep a Maybe type because in fact there is a possibility of having no result or one (extract sometimes from many) from the databases, so there is a possibility for Nothing i must keep and handle for the next instructions... thanks On Thu, Jan 3, 2019 at 3:54 PM Neil Mayhew < neil_mayhew@users.sourceforge.net> wrote:
On 2019-01-03 12:43 AM, Ganesh Sittampalam wrote:
If you did have [Maybe Text] you could use the library function
catMaybes :: [Maybe a] -> [a]
to both do the filtering and change the types.
...
But in your case you actually have [Only (Maybe Text)] rather than [Maybe Text] so catMaybes won't work. One option is to use a list comprehension instead:
let fltWDS = [Only a | Only (Just a) <- bd_rows_WDS]
It probably would be helpful to remove the Only wrapper at this stage, so this might be even better:
let fltWDS = [a | Only (Just a) <- bd_rows_WDS]
The way to do it with catMaybes would be to map with fromOnly first:
let fltWDS = catMaybes (map fromOnly bd_rows_WDS)
As Ganesh shows, there's no need for a type annotation after you've done the query, because the compiler can infer the type [Text] from the types of the functions that are used. The annotations are necessary with query only because it's polymorphic and can work with a wide variety of types. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (3)
-
Damien Mattei
-
Ganesh Sittampalam
-
Neil Mayhew