Crickey. You're still the man, lol :)


On Tue, Mar 24, 2015 at 6:13 AM, Bob Hutchison <hutch-lists@recursive.ca> wrote:

> On Mar 23, 2015, at 10:38 PM, Timothy Washington <twashing@gmail.com> wrote:
>

[snip]

...

You seem set on lenses. So if you write that move function like this (in case anyone’s wondering, I happen to know this isn’t a homework question):

data Piece = X | O | E deriving Show

move :: a -> b1 -> ASetter a b a1 b1 -> b
move board position piece = board & position .~ piece

This’ll work. But how are you going to get the position? If you’re given an integer based coordinate, as you seem to want from your definitions of Position, then you’re going to have to do something ugly.

This is a good point. I'm not particularly attached to lenses. That was just the conclusion I reached, in order to reach into and manipulate my original nested lists. I didn't see a way to do nested list updates in Data.List, on hackage. But now I see the difference between that and Data.Array (indexable, etc).

I'll come back to Lenses later on, just because now I'm curious. I'm happy for the Position to be "data Position = SomeLensType SomeLensType deriving Show", where ":t _2 => SomeLensType". Or something else that accommodates lens' data types.... but baby steps :)
 

Why not just go with an array and be done with it? Something like this (with your original definition of Piece):

import Data.Array

data Piece' = X | O | E deriving Show
type Position' = (Int,Int)
type Board' = Array Position’ Piece'

board' :: Board'
board' = array ((1,1),(3,3)) [((i,j), E) | i <- [1,2,3], j <- [1,2,3]]

move' :: Board' -> Piece' -> Position' -> Board'
move' board piece pos = board // [(pos, piece)]

This works swimmingly. So excellent point. 


If you want a slightly less ugly of looking at the board

import qualified Data.List.Split as S

pp board = mapM_ print $ S.chunksOf 3 $ elems board

will display the board something like:

[E,E,E]
[E,E,E]
[E,E,E]

I hope I didn’t say too much.

Not at all. These are exactly the kinds of hints that I need. In fact, with the // and array functions, this makes a lot of sense. And I used that and the board beautifier chunk, to create this. 

import Data.Array
import qualified Data.List.Split as S

data Piece' = X | O | E deriving Show
type Position' = (Int,Int)
type Board' = Array Position' Piece'

board' :: Board'
board' = array ((1,1),(3,3)) [((i,j), E) | i <- [1,2,3], j <- [1,2,3]]

ppb' :: Board' -> IO()
ppb' b = mapM_ print $ S.chunksOf 3 $ elems b

move' :: Board' -> Piece' -> Position' -> Board'
move' board piece pos = board // [(pos, piece)]

Now, I can pass in the board, piece, and position, to get my expected result.

λ> board'
array ((1,1),(3,3)) [((1,1),E),((1,2),E),((1,3),E),((2,1),E),((2,2),E),((2,3),E),((3,1),E),((3,2),E),((3,3),E)]

λ> let b1 = move' board' X (1,3)
λ> b1 
array ((1,1),(3,3)) [((1,1),E),((1,2),E),((1,3),X),((2,1),E),((2,2),E),((2,3),E),((3,1),E),((3,2),E),((3,3),E)]

λ> ppb' b1 
[E,E,X]
[E,E,E]
[E,E,E] 


Cheers,
Bob


Cool ! 
Cheers :) 

Tim Washington 
Interruptsoftware.com