Haskell -- ちょっと Lens の お勉強 ++ vty って何 ++ ちょっと改良 ++ ちょっと實驗

brick モジュールを試してみてゐた

Haskell -- brick を使ってみる - あしひきの

Haskell -- brick を使ってみる 2 - あしひきの

その中に どちらも

makeLenses ''St

といふ記述があり この Lens といふやつが 何かしてることは明らかだった
なので ちょっと Lensについて 調べてみた(「Haskell入門」)

data St =
    St { _focusRing :: F.FocusRing Name
       , _edit1 :: E.Editor String Name
       , _edit2 :: E.Editor String Name
       }

makeLenses ''St

なんとなく理解したのは
アンダーバーをつけて レコードを定義し (_focusRing とか _edit1 とか) makeLenses をすると

st^.focusRing

のやうにして 「^.」を使って データにアクセスできるよってことみたいだ
ってこれだけかいっ!
ただ CustomEventDemoのところで見たやうに
%= とか .= とかいったやつも Lensが提供する機能みたいで
變數の代入っぽく書くコードを自然につくれてゐる といふすごさはあるし
たぶん もっと色んなデータ構造を経験すれば そのすごさが もっと實感できるんだらう

あと vty についても 氣にはなってゐたので 一應調べてみた
Hackage のタイトル "A simple terminal UI library" で これが何なのか 少しは分かった
ターミナルの表示関連とかをするやつなんだな〜とか(めっちゃてきとー)

それと CustomEventDemo を
ただ カウンターだけ表示するものにしてみた

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Main(main) where

import Lens.Micro ((^.))
import Lens.Micro.TH (makeLenses)
import Lens.Micro.Mtl ((%=))
import Control.Monad (void, forever)
import Control.Concurrent (threadDelay, forkIO)
import qualified Graphics.Vty as V

import Brick.BChan (newBChan, writeBChan)
import Brick.Main (App(..), showFirstCursor, customMain, halt)
import Brick.AttrMap (attrMap)
import Brick.Types (Widget, EventM, BrickEvent(..))
import Brick.Widgets.Core(str)

data CustomEvent = Counter deriving Show

data St = St { _stCounter :: Int }

makeLenses ''St

drawUI :: St -> [Widget ()]
drawUI st = [a]
    where a = (str $ "Counter value is: " <> (show $ st^.stCounter))

appEvent :: BrickEvent () CustomEvent -> EventM () St ()
appEvent e =
    case e of
        VtyEvent (V.EvKey V.KEsc []) -> halt
        AppEvent Counter -> stCounter %= (+1)
        _ -> return ()

initialState :: St
initialState = St { _stCounter = 0 }

theApp :: App St CustomEvent ()
theApp =
    App { appDraw = drawUI
        , appChooseCursor = showFirstCursor
        , appHandleEvent = appEvent
        , appStartEvent = return ()
        , appAttrMap = const $ attrMap V.defAttr []
        }

main :: IO ()
main = do
    chan <- newBChan 10

    void $ forkIO $ forever $ do
        writeBChan chan Counter
        threadDelay 1000000

    let buildVty = V.mkVty V.defaultConfig
    initialVty <- buildVty
    void $ customMain initialVty buildVty (Just chan) theApp initialState

シンプルなタイマーだよね これって
んで ちょっと實驗した

newBChan 10

のところを

newBChan 1

に變更した
結果ーーー普通に動いた
次に

newBChan 0

とした
そしたらーー
カウンタ が 0 のまま 動かなくなった
ふむふむーーなるほどねー(全然わかってない)
ま そのうち考へやう
てなことで