#web-encodingsのWeb.Encodings.StringLikeでStringLikeクラスがexportされていて、
#instance宣言として[Char]のほかにData.TextのTextとかもちゃんとあるんだけど
#なぜかimportしてもStringLike Textのinstance宣言が必要って言われるのはなぜ?
#ghciで:m +Web.Encodings.StringLikeってしても
#classの定義の下にはinstance StringLike [Char]しか出てこない
#どの辺りが面倒ですか?
#どのあたりって言われてもw
#import Data.Textである程度関数があるけど
#できればqualifiedしたくないので
#まず、OverloadedStrings を指定して、リテラルが使えるようにしてますか?
#Preludeからのものはhidingとかするわけですが
#はい
#もちろん
#import Data.Text (Text)
#import qualified Data.Text as T
#とすると、よろし。
#そこでqualifiedすると全部T.付けて回らないといけないのがいやかなーと思って
#できればData.Textの関数はそのまま使いたかったんだけど
#あとは、トップレベルの関数でパターンマッチできなくなるので、ガードで分岐するスタイルに慣れる必要がありますね。
#Data.Text のどの関数ですか?
#パターンマッチできないのは当然なのでそこは最後になんとかしようと
#intercalate,unlines,last,concatMapなどなど文字列として扱ってた関数全部
#View パターンは、世界を救いますか? > どなたか
#ああ、全部 T. を付けましょう。
#うーん、そうなるのか。
#ByteString も同様のスタイルです。
#ところで、import Web.Encodings.StringLikeしてもTextに対するStringLikeのinstance宣言が見えないっぽいんですが、なんででしょう?
##このモジュールなんだけど
#もともとWeb.Encodings.encodeUrl
#を使ってて、こいつの引数をStringからTextにしたわけですが、
#なんかTextもインスタンス宣言されてるっぽいから
#Web.Encodings.StringLikeをimpoerしてみたんだけど
#なんか見えない様子。
#ほんとだ。見えませんね。
#Data.Text を import すると、なぜか instance が見えるようになりますね。
#instance 宣言って、data 定義も import してはじめて見えるようになるものですか?
#おお、なるほど、でも手元のコードではData.Textをimportしてるのに見えない。
#ロードそのものに失敗しているからか
#いや、エラーがTextに対するStringLikeのinstance宣言をしないとダメよって言われる。
#なぜだ
#動きますよ。
#{-# LANGUAGE OverloadedStrings #-}
module Main where
import Web.Encodings.StringLike ()
import Data.Text (Text)
import qualified Data.Text as T
main :: IO ()
main = do
let foobar = "foobar" :: Text
print $ "foo" `T.isPrefixOf` foobar
#あら
#このコードは、そちらで動きますか?
#cabal check で、インストールしたライブラリが壊れてないか確かめることもお勧めします。
#壊れていると、いろいろメッセージが出ます。壊れていないなら、何も言いません。
#うごきますね。
#StringLike()なのか
#あ、単に警告を消すために () を付けているだけです。
#お
#instance しか欲しくないと明示しただけです。
#アップしてもらったコードに
#import Web.Encodings (encodeUrl)
#をつけて
#encodeUrl ("foobar" :: Text)
#に変更したら出たな。
#これで使えると思ったんだが甘い?
#encodeUrlはStringLike a => a -> a
#{-# LANGUAGE OverloadedStrings #-}
module Main where
import Web.Encodings (encodeUrl)
import Web.Encodings.StringLike ()
import Data.Text (Text)
main :: IO ()
main = print $ encodeUrl ("foobar" :: Text)
#何の問題も
#なくうごきますよ。
#{-# LANGUAGE OverloadedStrings #-}
module Main where
import Web.Encodings (encodeUrl)
import Web.Encodings.StringLike ()
import Data.Text (Text)
import qualified Data.Text as T
main :: IO ()
main = do
let foobar = encodeUrl ("foobar" :: Text)
print $ "foo" `T.isPrefixOf` foobar
#こちらでは
#あうと
#あうととは具体的には?
#Test.hs:12:15:
No instance for (Web.Encodings.StringLike.StringLike Text)
arising from a use of `encodeUrl' at Test.hs:12:15-42
Possible fix:
add an instance declaration for
(Web.Encodings.StringLike.StringLike Text)
In the expression: encodeUrl ("foobar" :: Text)
In the definition of `foobar':
foobar = encodeUrl ("foobar" :: Text)
In the expression:
do { let foobar = encodeUrl ("foobar" :: Text);
print $ "foo" `T.isPrefixOf` foobar }
#どーん
#ちなみに
#ちょっと
#過去の環境にひきずられているので
#こちらでは、そのコードもうまく動きます。
#うえー
#web-encodings のバージョンはいくつですか?
#なんてこった
#0.3.0.4なんです。ちょっと古い。
#GHC6.12.3なんですが、以前0.3.0.5にあがった時に上げたら
#0.3.0.6 には上げられないんですか?
#ハマったんで上げずに0.3.0.4を使ってたんですよね。
#マイナーバージョンアップだし上げてみようかなぁ
#てか何故こんな変な現象に。。。
#cab sync
#cab delete -r web-encodings
#まずはアップしてみます。
#cab install web-encodings
#で、OK。
#cab check も忘れずに。
#これでダメならGHC7環境に移行してみようかなー
#今回package関係入れなおしたけど結構7系に移っちゃってるし。
#うわ、通った。
#バージョナップしたら、OK になったということですか?
#はい。cabはまだ使わせてもらってないんですが。
#cabal install web-encodingsで。
#0.3.0.6になったら
#さっきのコードはTrueを返すようになりました。
#Textのappendって何にマップしてます?そのまま`append`使ってますか?
#なんか(+++) =T.appendみたいにして
#そうそう。僕は、そうします。
#従来のコードの++を+++とかかきかえたいけど
#+++?
#しかし、+++ を使うのはアマちゃんなので。Blaze Builder を使う方がよくありませんか?
#それよくわからないんですが、Blaze Builderって何でしょう?
#RWH で、差分リストというのが出て来たのを覚えていますか?
#そこは
#覚えてないなぁ。
#関数合成を使って、右結合になるのを保証するテクニックです。
#あー、先日どっかで読んだかも。
#++だと大量にappendすると効率悪いよねってやつね。
#p 327 です。
#++ は左結合にすると O(N^2) ですが、右結合だと O(N) です。
#ああ、つまり++しているところをappendにするんじゃなくて、blaze builderを使って書き換えなよってことですか。
#どんな風に結合しても、右結合になるよう保証するのが差分リストです。
#差分リストのお化けライブラリが blaze builder というような位置づけです。
#プロファイルを取ってみて、+++ が問題になっているなら、blaze builder を使う方がいいでしょう。
#でもこれ*.Textなのが無さげですが、対応してるんですかね。
#プロファイルを取ってみると、驚くほどテキスト処理に時間を取られていることが分かりますよ。
#今はまずコードを移行するのが最優先なので
#効率は次かなー。
#簡単な使い方とかどっかに書いてたりしないかな。
#blaze-builder 自体が Text をサポートしています。
#Blaze.ByteString.Builder.Char.Utf8
#書き換えるなら、古いコードをモデルとして、新しく書き換えたコードをテストすると安心ですね。
#text の append って Stream Fusion で融合変換可能ではなかったかしら?
#あーっ、append 自体は Stream Fuison しますが、text で提供されている関数が全て Stream Fusion の対象になるとは限らないわけね。
#text には Stream Fusion の対象にならない関数がそこそこあるので、単純に Stream Fusion するだけではダメで差分リスト等の解決策が必要と。そういうことですね。 http://j.mp/lfIpPc ##text では性能問題について気づいたプログラマーが Data.Text.Lazy.Builder や blaze-builder などを使って自分の手で解決するという方針をとっているみたいですし。
#あっ、stream-fusion のも問題への直接の解決策ではなく、Stream Fusion しようとした対象が Stream Fusion 可能でない場合にかえtって効率が悪くなる問題を解決というものですね。
#(内容忘れていて、間違った発言をしてしまったので訂正します。)
#結局のところ使ってるライブラリ関係もTextをターゲットにしてくれてないと、その周辺がpack/unpackの嵐で悲しい。
#And you "Show"!?
#And you "FilePath"!?
#Text 型には Show クラスのインスタンスがありますが、それではダメですか?
#いや、そうではなく、Intとかの数値をshow xとして埋めてるところがあるの。
#そいつを受けてたのがStringだったんだけど、こいつの型がStringからTextに変わっているからshowじゃダメになったわけ。
#ぬ、emacs上だと解決してたのに…
#ghcを直接呼んでコンパイルしようとしたらまたinstance宣言足りないっていわれる。
#なんかweb-encoding-0.3.0.4を見てしまっている気がする。
#なるほど。そういう意味でしたか。それは確かに Text への変更で煩わしいところですね。 > Show
#結局Stringに軸足をおいてるライブラリを使っているから、yesodフレームワークだけTextに移行してても結構煩雑。
#Yesod.JsonとかYesod.AtomFeedみたくStringのままのものもあって、まだまだ移行するの早すぎるのかと思ったり。
#使っている人間もまだまだ少いから、こういうのをチマチマレポートして修正していってもらわないといけないのかとも思ったり。