Use a list as data for a data type?

Lets say I have a data type like so: data IpAddress = IpAddress {$ o1 :: !Int,$ o2 :: !Int,$ o3 :: !Int,$ o4 :: !Int$ } deriving (Show)$ which you can create by doing: IpAddress 192 168 1 1 Is there a way to do the same thing with the input data in a list? Like: IpAddress [192,168,1,1] or using some operator (or combination of operators):Like (I'm guessing (<????>) isn't in use): IpAddress <????> [192,168,1,1] Thanks in advance, Bryce

On Fri, Feb 22, 2013 at 10:43:32AM -0800, Bryce Verdier wrote:
Lets say I have a data type like so:
data IpAddress = IpAddress {$ o1 :: !Int,$ o2 :: !Int,$ o3 :: !Int,$ o4 :: !Int$ } deriving (Show)$
which you can create by doing: IpAddress 192 168 1 1
Is there a way to do the same thing with the input data in a list? Like: IpAddress [192,168,1,1]
or using some operator (or combination of operators):Like (I'm guessing (<????>) isn't in use): IpAddress <????> [192,168,1,1]
No, there isn't. But you can make a function ipAddress :: [Int] -> IpAddress ipAddress [a,b,c,d] = IpAddress a b c d -Brent

On Fri, Feb 22, 2013 at 02:07:43PM -0500, Brent Yorgey wrote:
On Fri, Feb 22, 2013 at 10:43:32AM -0800, Bryce Verdier wrote:
Lets say I have a data type like so:
data IpAddress = IpAddress {$ o1 :: !Int,$ o2 :: !Int,$ o3 :: !Int,$ o4 :: !Int$ } deriving (Show)$
which you can create by doing: IpAddress 192 168 1 1
Is there a way to do the same thing with the input data in a list? Like: IpAddress [192,168,1,1]
or using some operator (or combination of operators):Like (I'm guessing (<????>) isn't in use): IpAddress <????> [192,168,1,1]
No, there isn't. But you can make a function
ipAddress :: [Int] -> IpAddress ipAddress [a,b,c,d] = IpAddress a b c d
For that matter you can define the operator (<????>) yourself: (<????>) :: (a -> a -> a -> a -> b) -> [a] -> b f <????> [a,b,c,d] = f a b c d Not sure how useful it is though. -Brent

Brent, Thank you for the responses. I appreciate it. Bummer about there not being some kind of built-in/generic shortcut. Bryce On 02/22/2013 12:14 PM, Brent Yorgey wrote:
On Fri, Feb 22, 2013 at 02:07:43PM -0500, Brent Yorgey wrote:
On Fri, Feb 22, 2013 at 10:43:32AM -0800, Bryce Verdier wrote:
Lets say I have a data type like so:
data IpAddress = IpAddress {$ o1 :: !Int,$ o2 :: !Int,$ o3 :: !Int,$ o4 :: !Int$ } deriving (Show)$
which you can create by doing: IpAddress 192 168 1 1
Is there a way to do the same thing with the input data in a list? Like: IpAddress [192,168,1,1]
or using some operator (or combination of operators):Like (I'm guessing (<????>) isn't in use): IpAddress <????> [192,168,1,1] No, there isn't. But you can make a function
ipAddress :: [Int] -> IpAddress ipAddress [a,b,c,d] = IpAddress a b c d For that matter you can define the operator (<????>) yourself:
(<????>) :: (a -> a -> a -> a -> b) -> [a] -> b f <????> [a,b,c,d] = f a b c d
Not sure how useful it is though.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On 02/22/2013 03:40 PM, Bryce Verdier wrote:
Brent,
Thank you for the responses. I appreciate it. Bummer about there not being some kind of built-in/generic shortcut.
You can try with a fold:
(((IpAddress $ 1) $ 2) $ 3) $ 4 IpAddress 1 2 3 4
If you consider the type of the constructor along with the types passed through the fold, it might become clearer why this can't work in general.

On Fri, Feb 22, 2013 at 12:40 PM, Bryce Verdier
Brent,
Thank you for the responses. I appreciate it. Bummer about there not being some kind of built-in/generic shortcut.
Bryce
I am curious about what motivated your question, since it's hard to imagine a simpler alternative to writing "IpAddress 1 2 3 4". -Karl Voelker

Hi, Note: Following code is a solution for a problem from hackerrank.com (Category: Artifical Intelligence / Single Player Games / Bot saves princess). Here is my first Haskell code! Short explanation of the problem: it's standard path finding problem, we have a matrix where 'm' denotes the bot, 'p' denotes the princess and '-' is for empty space. Sample input (grid size followed by the grid itself, where each row is separated by new line): 3 --- -m- p-- Sample output: DOWN LEFT Here is the code: module Main where import Data.List import Data.Maybe type Size = Int type Grid = [String] type Path = [Move] type Heuristic = [[Int]] type Position = (Int,Int) data Move = LEFT | RIGHT | UP | DOWN deriving Show getSize :: IO Size getSize = readLn getGrid :: Size -> IO Grid getGrid s = sequence $ replicate s getLine getHeuristic :: Size -> Position -> Heuristic getHeuristic s p = map (getHeuristic' s p) [0..s-1] getHeuristic' :: Size -> Position -> Int -> [Int] getHeuristic' s p y = map (getHeuristic'' p y) [0..s-1] getHeuristic'' :: Position -> Int -> Int -> Int getHeuristic'' (x2, y2) y1 x1 = abs (x1 - x2) + (abs (y1 - y2)) getPos :: Char -> Size -> Grid -> Position getPos c s g = (i `mod` s, i `div` s) where g' = concat g i = fromJust $ elemIndex c g' getSteps :: Size -> Heuristic -> Position -> Position -> Path getSteps s h b p | b == p = [] | otherwise = let (m,b') = getStep s h b in m : (getSteps s h b' p) getStep :: Size -> Heuristic -> Position -> (Move,Position) getStep s h b = head $ sortBy compareCost (getAvailableSteps s h b) where compareCost (_,(x1,y1)) (_,(x2,y2)) = compare (h !! y1 !! x1) (h !! y2 !! x2) getAvailableSteps :: Size -> Heuristic -> Position -> [(Move,Position)] getAvailableSteps s h (x,y) = up ++ down ++ left ++ right where up = if y > 0 then [(UP, (x, y - 1))] else [] down = if y < (s - 1) then [(DOWN, (x, y + 1))] else [] left = if x > 0 then [(LEFT, (x - 1, y))] else [] right = if x < (s - 1) then [(RIGHT, (x + 1, y))] else [] main :: IO () main = do size <- getSize grid <- getGrid size let botPos = getPos 'm' size grid princessPos = getPos 'p' size grid heuristic = getHeuristic size princessPos result = getSteps size heuristic botPos princessPos mapM_ print result Please point out all my mistakes. Emanuel

On Sat, Feb 23, 2013 at 04:39:53PM +0100, Emanuel Koczwara wrote:
Hi,
Note: Following code is a solution for a problem from hackerrank.com (Category: Artifical Intelligence / Single Player Games / Bot saves princess).
Looks pretty good overall. One note is that using lists of lists for Grid and Heuristic will be slow, especially Heuristic since you do lots of repeated lookups. For small grids it really doesn't make much difference, but if you wanted to run it on larger grids you might notice. Since both the Grid and Heuristic values are created once and then used in a read-only fasion, this is a perfect opportunity to use arrays: see http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array... Using read-only arrays is really quite simple (as opposed to read/write arrays which require a monad of some sort). -Brent
Here is my first Haskell code! Short explanation of the problem: it's standard path finding problem, we have a matrix where 'm' denotes the bot, 'p' denotes the princess and '-' is for empty space.
Sample input (grid size followed by the grid itself, where each row is separated by new line):
3 --- -m- p--
Sample output:
DOWN LEFT
Here is the code:
module Main where
import Data.List import Data.Maybe
type Size = Int
type Grid = [String]
type Path = [Move]
type Heuristic = [[Int]]
type Position = (Int,Int)
data Move = LEFT | RIGHT | UP | DOWN deriving Show
getSize :: IO Size getSize = readLn
getGrid :: Size -> IO Grid getGrid s = sequence $ replicate s getLine
getHeuristic :: Size -> Position -> Heuristic getHeuristic s p = map (getHeuristic' s p) [0..s-1]
getHeuristic' :: Size -> Position -> Int -> [Int] getHeuristic' s p y = map (getHeuristic'' p y) [0..s-1]
getHeuristic'' :: Position -> Int -> Int -> Int getHeuristic'' (x2, y2) y1 x1 = abs (x1 - x2) + (abs (y1 - y2))
getPos :: Char -> Size -> Grid -> Position getPos c s g = (i `mod` s, i `div` s) where g' = concat g i = fromJust $ elemIndex c g'
getSteps :: Size -> Heuristic -> Position -> Position -> Path getSteps s h b p | b == p = [] | otherwise = let (m,b') = getStep s h b in m : (getSteps s h b' p)
getStep :: Size -> Heuristic -> Position -> (Move,Position) getStep s h b = head $ sortBy compareCost (getAvailableSteps s h b) where compareCost (_,(x1,y1)) (_,(x2,y2)) = compare (h !! y1 !! x1) (h !! y2 !! x2)
getAvailableSteps :: Size -> Heuristic -> Position -> [(Move,Position)] getAvailableSteps s h (x,y) = up ++ down ++ left ++ right where up = if y > 0 then [(UP, (x, y - 1))] else [] down = if y < (s - 1) then [(DOWN, (x, y + 1))] else [] left = if x > 0 then [(LEFT, (x - 1, y))] else [] right = if x < (s - 1) then [(RIGHT, (x + 1, y))] else []
main :: IO () main = do size <- getSize grid <- getGrid size let botPos = getPos 'm' size grid princessPos = getPos 'p' size grid heuristic = getHeuristic size princessPos result = getSteps size heuristic botPos princessPos mapM_ print result
Please point out all my mistakes.
Emanuel
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Hi, Dnia 2013-02-23, sob o godzinie 17:35 -0500, Brent Yorgey pisze:
On Sat, Feb 23, 2013 at 04:39:53PM +0100, Emanuel Koczwara wrote:
Hi,
Note: Following code is a solution for a problem from hackerrank.com (Category: Artifical Intelligence / Single Player Games / Bot saves princess).
Looks pretty good overall. One note is that using lists of lists for Grid and Heuristic will be slow, especially Heuristic since you do lots of repeated lookups. For small grids it really doesn't make much difference, but if you wanted to run it on larger grids you might notice. Since both the Grid and Heuristic values are created once and then used in a read-only fasion, this is a perfect opportunity to use arrays: see
http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array...
Using read-only arrays is really quite simple (as opposed to read/write arrays which require a monad of some sort).
Thank you, I will try Arrays. Handling list of lists is very hard for me. Please look at this code: http://hpaste.org/82925 (indexedGrid and getDirty). In C/C++ it's very natural for me, here it looks like i'm missing something. Emanuel

On Sun, Feb 24, 2013 at 12:15:05AM +0100, Emanuel Koczwara wrote:
Hi,
Dnia 2013-02-23, sob o godzinie 17:35 -0500, Brent Yorgey pisze:
On Sat, Feb 23, 2013 at 04:39:53PM +0100, Emanuel Koczwara wrote:
Hi,
Note: Following code is a solution for a problem from hackerrank.com (Category: Artifical Intelligence / Single Player Games / Bot saves princess).
Looks pretty good overall. One note is that using lists of lists for Grid and Heuristic will be slow, especially Heuristic since you do lots of repeated lookups. For small grids it really doesn't make much difference, but if you wanted to run it on larger grids you might notice. Since both the Grid and Heuristic values are created once and then used in a read-only fasion, this is a perfect opportunity to use arrays: see
http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array...
Using read-only arrays is really quite simple (as opposed to read/write arrays which require a monad of some sort).
Thank you, I will try Arrays. Handling list of lists is very hard for me. Please look at this code: http://hpaste.org/82925 (indexedGrid and getDirty). In C/C++ it's very natural for me, here it looks like i'm missing something.
In C/C++ you get to use arrays with indexing. Lists are entirely different, so it's no surprise that something natural in C/C++ should feel foreign here. Indeed, I don't think lists are the right data structure for you to be using. If you use arrays I think this code will become much simpler too. A good rule of thumb is that lists should be primarily used as a *control structure* (i.e. to describe something that would be done with a loop in an imperative language). If you find yourself using lists as a *data structure*, especially a random-access one, you probably ought to be using something else instead (Data.Sequence, arrays, ...) -Brent

Brent Yorgey wrote:
Since both the Grid and Heuristic values are created once and then used in a read-only fasion, this is a perfect opportunity to use arrays: see
http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array...
Using read-only arrays is really quite simple (as opposed to read/write arrays which require a monad of some sort).
Brent, out of curiosity, why Array instead of Data.Vector? Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

Hi, 1 main = do 2 line <- getLine 3 putStrLn line 4 line <- getLine 5 putStrLn line Here I have 'line' first bounded with a value at line 2, and then at line 4. It looks like I can set (or bind) a variable in 'do' block more than once, and it looks like it's a destructive update. But as I'm thinking about this more and more, it appears that the first and second 'line' are just an ordinary immutable variables. Line 4 just hides the 'line' from line 2 (outer lambda). Am I right? Emanuel

Hi,
On 24 February 2013 10:41, Emanuel Koczwara
it appears that the first and second 'line' are just an ordinary immutable variables. Line 4 just hides the 'line' from line 2 (outer lambda). Am I right?
Exactly. You can try desugaring the do notation to see what's going on even more clearly. Best, Ozgur

On Sun, Feb 24, 2013 at 06:29:22PM +1100, Erik de Castro Lopo wrote:
Brent Yorgey wrote:
Since both the Grid and Heuristic values are created once and then used in a read-only fasion, this is a perfect opportunity to use arrays: see
http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array...
Using read-only arrays is really quite simple (as opposed to read/write arrays which require a monad of some sort).
Brent, out of curiosity, why Array instead of Data.Vector?
No reason other than that I'm more familiar with Array. Upon inspection of Data.Vector it looks like that would indeed be a better choice. -Brent

Brent Yorgey wrote:
Brent, out of curiosity, why Array instead of Data.Vector?
No reason other than that I'm more familiar with Array. Upon inspection of Data.Vector it looks like that would indeed be a better choice.
Thank Brent. That confirms my own choice :-). Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/
participants (7)
-
Brent Yorgey
-
Bryce Verdier
-
Emanuel Koczwara
-
Erik de Castro Lopo
-
Karl Voelker
-
Michael Orlitzky
-
Ozgur Akgun