[Haskell-beginners] Dipping Toes Into Haskell
Timothy Washington
twashing at gmail.com
Sun Mar 22 16:33:18 UTC 2015
So I've finally had a chance to revisit my tictactoe game.
import Control.Lens
data Piece = X | O | E deriving Show
type Row = [Piece]
type Board = [Row]
*data Position = Int Int deriving Show*
-- put an X or O in a position
*move :: Board -> Piece -> Position -> Board*
move board piece position = board
main :: IO ()
main = putStrLn "Hello World"
-- using Lenses
-- https://github.com/ekmett/lens/wiki/Examples
-- http://lens.github.io/tutorial.html
--
http://blog.jakubarnold.cz/2014/07/14/lens-tutorial-introduction-part-1.html
--let r1 = (E,E,E)
--let r2 = (E,E,E)
--let r3 = (E,E,E)
--let board = (r1,r2,r3)
Now, if I want to make a move, I'll want to set a *piece* on a *position*,
on a *board*. Let's assume the board has the following shape.
λ> let r1 = (E,E,E)
λ> let r2 = (E,E,E)
λ> let r3 = (E,E,E)
λ> let board = (r1,r2,r3)
((E,E,E),(E,E,E),(E,E,E))
To return an updated board, I dug around and *i)* couldn't find a core
Haskell equivalent to Clojure's update-in
<http://clojuredocs.org/clojure.core/update-in>. *ii)* Zippers only deal
with trees of left / right nodes. *iii)* So that left me with Control.Lens
<https://github.com/ekmett/lens/wiki/Examples>. Now I can easily inspect
and update the board like so.
λ> board^*._**2._1*
E
λ> set (*_2._1*) 42 board
((E,E,E),(42,E,E),(E,E,E))
I can then parameterize _2 or _1 like so.
λ> let a = _2
λ> board ^. a
(E,E,E)
But I can't figure out how to include that parameter's type into a
*Position* type definition. I've tried these unsuccessfully.
*data Position = Int Int deriving Show -- original type definition*
*data Position = Simple Lens (Int a) (Int a) deriving Show -- failing try
1*
move :: Board -> Piece -> Position -> Board
move board piece position = set (position) piece board -- want to use this
instead of "set (*_2._1*) 42 board"
Any ideas?
:)
Tim Washington
Interruptsoftware.com <http://interruptsoftware.com>
On Thu, Mar 12, 2015 at 5:18 PM, Timothy Washington <twashing at gmail.com>
wrote:
> Veeery nice. Thanks for your insights.
>
> The Typeclass stuff making a lot more sense now. And hence ghc-mod's
> (Interactive-Haskell's) behaviour makes more sense to me. It's working like
> a charm.
>
> I'll play around with nested list manipulation this evening.
>
>
> Cheers
>
> Tim Washington
> Interruptsoftware.com <http://interruptsoftware.com>
>
>
> On Thu, Mar 12, 2015 at 8:03 PM, Mike Meyer <mwm at mired.org> wrote:
>
>> On Thu, Mar 12, 2015 at 6:02 PM, Timothy Washington <twashing at gmail.com>
>> wrote:
>>
>>> To get started, I'm trying to implement a simple *tictactoe* game. And
>>> I would like to be able to represent a Piece on the board, as either the
>>> string "X" or "O". This is what I have so far.
>>>
>>> module Main where
>>>
>>> data Piece = X | O
>>> type Row = [Piece]
>>> type Board = [Row]
>>>
>>> -- put an X or O in a position
>>> move :: Board -> Piece -> Board
>>> move board piece = board
>>>
>>> -- check win vertically
>>> -- check win horizontally
>>> -- check win diagonally
>>>
>>> main :: IO ()
>>> main = putStrLn "Hello World"
>>>
>>>
>>>
>>> *A)* Now, I'd like to be able to *load code interactively*, preferably
>>> within emacs. However I don't have access to my types with *ghci* or *ghc-mod
>>> (Interactive-Haskell)*. In either case, this call fails with the below
>>> error.
>>>
>>>
>>> let p = Piece X
>>> <interactive>:20:9-13: Not in scope: data constructor `Piece'
>>>
>>>
>> Piece is the data TYPE. It has two constructors, X, and O. If you load
>> your module into ghci, you can do ":t X" to get the type of X, which is
>> Piece. You want to do "let p = X" here.
>>
>> Check your mode docs while editing the haskell file. There should be a
>> command to load the current buffer into a ghci running in an interactive
>> emacs buffer.
>>
>>
>>> *B)* And how do I make a *custom datatype* that's one of two strings
>>> (enumeration of either "X" or "O"). Cabal builds and runs the abouve code,
>>> so I know it can compile. But I'm confused as to where X or O is defined,
>>> and how I would supply it as an input.
>>>
>>
>>
>> As noted, you can derive "Show" so that Piece types print as "X" and "O".
>> Similarly, you can derive "Read":
>>
>> data Piece = X | O deriving (Show, Read)
>>
>> so that you can then read "X" and get back an X when the context calls
>> for a Piece value:
>>
>> *Main> read "X" :: Piece
>>
>> X
>>
>> However, this isn't used a lot, as it tends to be slow and not very
>> flexible for more complex types. For instance, it will let you read in
>> lists of Pieces and lists of lists, but you'l lhave to use the list syntax,
>> not something that looks like an actual board when printed.
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150322/7f429bb5/attachment.html>
More information about the Beginners
mailing list