[Haskell-beginners] Dipping Toes Into Haskell
Timothy Washington
twashing at gmail.com
Wed Mar 25 03:37:42 UTC 2015
Crickey. You're still the man, lol :)
On Tue, Mar 24, 2015 at 6:13 AM, Bob Hutchison <hutch-lists at recursive.ca>
wrote:
>
> > On Mar 23, 2015, at 10:38 PM, Timothy Washington <twashing at 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
<https://hackage.haskell.org/package/base-4.7.0.2/docs/Data-List.html>. But
now I see the difference between that and Data.Array
<https://hackage.haskell.org/package/array-0.5.0.0/docs/Data-Array.html>
(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 <http://interruptsoftware.com/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150324/f10e4f6d/attachment-0001.html>
More information about the Beginners
mailing list