[Haskell-beginners] Dipping Toes Into Haskell

Bob Hutchison hutch-lists at recursive.ca
Mon Mar 23 11:57:58 UTC 2015


Hi Tim,

Staying from clojure? :-)

> On Mar 22, 2015, at 12:33 PM, Timothy Washington <twashing at gmail.com> wrote:
> 
> 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 <https://github.com/ekmett/lens/wiki/Examples>
> -- http://lens.github.io/tutorial.html <http://lens.github.io/tutorial.html>
> -- http://blog.jakubarnold.cz/2014/07/14/lens-tutorial-introduction-part-1.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. 

Or you could use an two dimensional array of Positions instead (Data.Array).

> 
> λ> 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)

You can probably find the type of _1, _2, _3 in the repl, and use that in your code below.

> 
> 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

These are very suspicious. Did you intend to define constructors ‘Int’ and ‘Simple’? Maybe you meant something like:

data Position = Position Int Int deriving Show

In which case you’ll have a type called ‘Position’ and a constructor with the same name.

Cheers,
Bob

> 
> 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 <mailto: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 <mailto:mwm at mired.org>> wrote:
> On Thu, Mar 12, 2015 at 6:02 PM, Timothy Washington <twashing at gmail.com <mailto: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.
> 
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150323/1a995bb2/attachment.html>


More information about the Beginners mailing list