Home > Net >  Convert a list of Int to a custom Type in HASKELL
Convert a list of Int to a custom Type in HASKELL

Time:05-26

i m not sure if my approach is correct. So,

What i m trying to do is to convert a list of [[Int]] example :

[[1234, 5, 2], [4568, 7, 3], [7897, 6, 5]]

Into a list of [[Patient]].

data Patient = Patient { patientId :: Int, patientTemps :: Int, patientPriorite :: Int } deriving (Show)

The reason why i m doing this, it 's because i want to print "index patientId patientPriorite" something like :

1 1234 2

2 4568 3

3 7897 5

So i think if i will get [[Patient]] i will easly get access to my elements in the list.

CodePudding user response:

A simple way but this will throw an error if there's any invalid data (lists of length /= 3).

data Patient = Patient { patientId :: Int, patientTemps :: Int, patientPriorite :: Int } deriving (Show)

main :: IO ()
main = do
  let lists = [[1234, 5, 2], [4568, 7, 3], [7897, 6, 5]]
  print $ map (\[a, b, c] -> Patient a b c) lists

Output:

[Patient {patientId = 1234, patientTemps = 5, patientPriorite = 2},Patient {patientId = 4568, patientTemps = 7, patientPriorite = 3},Patient {patientId = 7897, patientTemps = 6, patientPriorite = 5}]

A safer way is to define a function that converts [Int] to Maybe Patient and then handle invalid data as you want:

import Data.Maybe (catMaybes)

data Patient = Patient { patientId :: Int, patientTemps :: Int, patientPriorite :: Int } deriving (Show)

listToPatient :: [Int] -> Maybe Patient
listToPatient [a, b, c] = Just $ Patient a b c
listToPatient _ = Nothing

main :: IO ()
main = do
  let lists = [[1234, 5, 2], [4568, 7, 3], [7897, 6, 5]]
  print $ map listToPatient lists
  -- Two ways to filter out the Nothing values: `catMaybes` or a list comprehension.
  print $ catMaybes $ map listToPatient lists
  print $ [patient | Just patient <- map listToPatient lists]

Output:

[Just (Patient {patientId = 1234, patientTemps = 5, patientPriorite = 2}),Just (Patient {patientId = 4568, patientTemps = 7, patientPriorite = 3}),Just (Patient {patientId = 7897, patientTemps = 6, patientPriorite = 5})]
[Patient {patientId = 1234, patientTemps = 5, patientPriorite = 2},Patient {patientId = 4568, patientTemps = 7, patientPriorite = 3},Patient {patientId = 7897, patientTemps = 6, patientPriorite = 5}]
[Patient {patientId = 1234, patientTemps = 5, patientPriorite = 2},Patient {patientId = 4568, patientTemps = 7, patientPriorite = 3},Patient {patientId = 7897, patientTemps = 6, patientPriorite = 5}]```

CodePudding user response:

You could write something like the below for the conversion:

f :: [[Int]] -> [Patient]
f [] = []
f ([x,y,z]:zs) = Patient { patientId = x, patientTemps = y, patientPriorite = z}: (f zs)
f _ = undefined

If all you want is to display your data with index, you could simply zip the original together with a list of integers, like so:

map (\x -> (fst x,(snd x)!!0, (snd x)!!1)) $ zip [1..] yourlist

That said, since the list items correspond to specific attributes, I would go with the first option.

  • Related