haskell-jp / questions #22

ghc-paths-0.1.0.9: using precompiled package
ghc-pkg.EXE: cannot find package ghc-paths-0.1.0.9
このようなエラーメッセージが出てきまして、他のプロジェクトでも同様の状況でした。
とりあえず .stack-work を消したり
~/.stack/ を消してみる、ですかね。。。
アドバイスありがとうございます。色々試してみたところ https://haskell.e-bigmoon.com/stack/tips/full-rebuild.html の一番下で直りました
extensibleについて再び質問です。
Associate k v xs => FieldName k -> Record xs -> v
という型の関数を書くにはどうすればよいでしょうか?
FieldName k はざっくりいうと Optic の 型シノニムなので普通のlensや mkField で作られたフィールドらしく
record ^. field みたいな式で取り出せるかな、と思ったのですが、
app\record-placeholder.hs:53:23: error:
    • Couldn't match type ‘LabelPhantom
                             k1
                             (Inextensible (Field Proxy) '[k1 ':> ()])
                             (Proxy (Inextensible (Field Proxy) '[k1 ':> ()]))’
                     with ‘Record xs -> Const a0 (Record xs)’
      Expected type: Control.Lens.Getter.Getting a0 (Record xs) a0
        Actual type: FieldName k1

という内容のコンパイルエラーで怒られてしまいました :disappointed:
OverloadedLabels を使わずに?
使っています。
で、 FieldName#field のように OverloadedLables で多相化された状態ではなく、 field :: FieldName k という型の変数として渡されます。
そこを FieldName k 以外の型にした方がいいんだろうか...
FieldNameは`FieldOptic`の特殊な場合で、Proxyと基本的に同じ役割を持ちます。`FieldOptic`の方はLensの機能を持っています
もしかして謎の https://hackage.haskell.org/package/extensible-0.4.9/docs/Data-Extensible-Label.html#v:-35338-
で変換するのが正解なんでしょうか?
引数がFieldNameでないといけないなら、itemAssoc(訊)で変換する必要がありますが、そうでない場合型をFieldOpticにすれば大丈夫だと思います
@iokasimov.m has joined the channel
言い忘れていましたが 、オプティックを多相なまま引数に取るのはアンチパターンと考えられているようです(ALensなどがあるのはそのため)。そこを考慮すると、 FieldName k を引数に取って、 hlookup (associate :: Membership xs (k ':> v) と書くのがよさそうです
ありがとうございます。
報告が遅くなりましたが、私の用途で FieldOptic k を引数にすると v の型がうまく定まらないのかコンパイルエラーになってしまったので、
rec ^. itemAssoc (Proxy :: Proxy k) と書いて解決しました。
Associate k v xs => というコンテキストだったので)
@j0td5ta0d1mt has joined the channel
Is there a way to inspect the definition of derived instances?
Say:
data Free f a = Pure a | Free (f (Free f a)) deriving Functor
data Tree a = Node a Tree Tree | Leaf a

のような循環した構造をextensibleで宣言するにはどうすればいいでしょうか?typeで愚直に宣言すると循環していると言ってエラーが出てしまったのですが……
data T a = N a (T a) (T a) | L a

多分こういう意味では?
data constructor fields の kind は * が必要
newtypeするのが無難です。data familyを活用して、再帰する為のラッパーを作るという力技もできなくはないです
ありがとうございます!
Equality constraintsに関する質問です。型変数aはFoo型もしくはBar型であるって制約を課すことは可能なのでしょうか。。`someFun :: (a ~ (Foo || Bar), Monad m) => m a` みたいな
実行環境ないので試してないのですが
import Data.Type.Bool
import Data.Type.Equality

someFun :: (a == Foo || a == Bar) ~ True => ...

とかはどうでしょう?
閉じた型族を使えば実現できます。
{-# LANGUAGE ConstraintKinds, TypeFamilies #-}
import Data.Constraint
data Foo
data Bar

type family IsFooOrBar x :: Constraint where
  IsFooOrBar Foo = ()
  IsFooOrBar Bar = ()
  IsFooOrBar x = Bottom

someFun :: (IsFooOrBar a, Monad m) => m a
someFun = undefined
わーありがとう。やってみます!
でも、その制約をしたら、後からどうやってFooとBarの型に取れるの?
open-unionを使うのが実用的で手っ取り早い解?
しかしこれもliftUnionを通すので引数そのまま渡すわけではないですね…
Haskellのジェネリクスは異種変換ではないですし,Rustのトレイトオブジェクトみたいなのを導入してしまったら結局は動的ディスパッチになる
パターンマッチとかで型によって静的分岐出来たらそれは実質的な関数オーバーロードですね
Haskellに関数オーバーロード入れてしまって良いんだっけ…?
@kanjiro_f has joined the channel
ansi-wl-pprint -> prettyprinter + prettyprinter-ansi-terminalの話が出てますが,ansi-wl-pprintのDocをprettyprinter + prettyprinter-ansi-terminalのDoc AnsiStyleに変換する関数って誰か作ってたりしますかね?(諸事情で変換したくて自分では書きたくないのですが)
https://github.com/ekmett/ansi-wl-pprint/issues/18
ありがとうございます、解決しました!
ざっくり説明しますと、
- サポートデスクからユーザー及び送られてきたチケットを解析するアプリを開発している。
- サポートデスクのAPIでチケットをフェッチすると以下のデータが得られる。
チケット
{ "tickets":[],
  "next_page": some_url
}

ユーザー
{ "users":[],
  "next_page": some_url
}

最初別々の関数で取得してたけど、一般化させようって話になった。
これがその結果です。発送はnotogawaさんが教えてくれたものと似ていると思います。
(`iteratePages`が取得関数です。)
https://github.com/input-output-hk/log-classifier/pull/19/commits/ef7b8e54df080e476053df1fdb3c9909bfd8f340
@sean.westfall has joined the channel
TemplateHaskellって、生成したコードは .hs で出力できるの?例えば
{-# LANGUAGE TemplateHaskell #-}
module Foo where

import Language.Haskell.TH.Syntax

foo = $(lift ("foo" ++ "bar"))

=======>
{-# LANGUAGE TemplateHaskell #-}
module Foo where

import Language.Haskell.TH.Syntax

foo = "foobar"

みたいな
ghc に -ddump-splices というオプションで、生成したソースを書き出すことはできますが、 .hs として直接コンパイルできるものではありません。
それは知ってるけど。。。直接repoにcommitできるようにしたいなあ。。。
変換してコピペしよう。
そして、自分で探して、コピペするには、多くなるとやばいなあ。
THの生成はローカル環境に関連あるから、THのコードを直接使えなくて。。。
そういうスクリプトを書くしかないでしょう。
要は直接依存してないパッケージ名の解決とimportする部分さえ吐き出せればいいんでそんなに難しくはないはず...
僕はhaskdogsを使ってます!
むしろこんなに色々あったのかー
特に考えもなく最初に見つけた hasktags を使ってました。色々あるのね。
:point_up: の4つ全部試したわけでもないし確かほかにもあったかと思いますが、とりあえず hasktags に戻ってます。 hothasktags はのLTSでビルドできなかったし...
あとちなみに、haskdogsは実際にはhasktagsのラッパーです。
無限リストを NonEmpty みたいに表現する常套手段って何かありますか?

ふつうにこのようにやると、
xs = [1..] :: [Int]
let (x: _) = head $ drop 10 xs

パーシャルだぜ、って警告されてしまいます。これを(できれば型で)なんとかしたいです。
ありがとうございます!みてみます!
お手軽な ghci :etags を使ってます。なんにも依存しない:sweat_smile:
type family Fst (t :: (a, b)) :: a where
  Fst '(a, b) = a

type family Snd (t :: (a, b)) :: b where
  Snd '(a, b) = b

extractedTuple :: '(Fst a, Snd a) :~: a

みたいなので, extractedTupleunsafeCoerce 無しに実装する方法ってありますでしょうか?もしくは,Fst/Sndの代用となるtype utilityってなんかあったりするのでしょうか?