haskell-jp / beginners #25 at 2024-09-21 17:43:22 +0900

アプリカティブ・スタイルについて質問させてください

data Ehdr = Ehdr {
    e_entry :: !Word64
    ,e_phoff :: !Word64
    ,e_shoff :: !Word64
    ,e_ehsize :: !Word16
    ,e_phentsize :: !Word16
    ,e_phnum :: !Word16
    ,e_shentsize :: !Word16
    ,e_shnum :: !Word16
    ,e_shstrndx :: !Word16
    } deriving Show

getEhdr :: Get Ehdr
getEhdr = do
    ... 省略 ...

    Ehdr e_entry e_phoff e_shoff <$>
        getWord16host <*> getWord16host <*> getWord16host <*>
        getWord16host <*> getWord16host <*> getWord16host

上記のようなコードがあり、これは想定通りに動作しています。

この中で、getWord16host <*> getWord16host ... という部分が複数出てきてしまっています。
これを replicate 6 getWord16host のような形にできないかといろいろと試しましたがうまくいきませんでした。

なにか良い書き方はありますか ?
ズバりの答えではないですが、このページの最下部のように join で引数を増やせるかもしれません https://ziphil.com/other/other/12.html
(↑ 解答ではなく雑談です :pray:)
知る限りTemplate Haskellでも使わない限り解決できないかと思いますね...
github で検索しても、みんな <$> ** <*> の書き方をしていました。
Template Haskell は少し調べてみましたが、今の自分では理解は難しそうでした、、

join のほうもすぐには理解できませんが、面白そうですので調べてみます。

ご回答ありがとうございました。
ちなみにもちろん、こういうふうに↓ベタに書きたいという訳ではないのですよね、おそらく。
(アプリ化ティブ風に中間変数も記述から消したい、というのがニーズですよね。)

getEhdr :: Get Ehdr
getEhdr = do
    [a, b, c, d, e, f] <- replicateM 6 getWord16host
    return $ Ehdr 100 200 300 a b c d e f
ちょっとズル(?)して、別途app6を作っておいて、以下とか。
(ただ、引数の数も6個の固定でなく可変個にしたいのですよね、おそらく、、、)

app6 f [x0, x1, x2, x3, x4, x5] = f x0 x1 x2 x3 x4 x5

getEhdr :: Get Ehdr
getEhdr = do
    app6 (Ehdr 100 200 300) <$> replicateM 6 getWord16host
@takenobu.hs
可変個にしたいのですよね
はい。getWord16host が続いていたので

雰囲気ですが、、
Ehdr 100 200 300 <$> foldl1 (<*>) $ replicate 6 getWord16host

こんな風に書けたら便利だな、って考えて質問してみましたが
固定数のところに可変のものを当てはめるようになって、難しそうですよね :sweat_drops:

いろいろ考えていただきありがとうございました。