テストを書いたら本体のバグが発覚しました, エラー時のレスポンスが捨てられてしまうのでhttpsJSONEitherは使わない, 検索した内容をtwitterに投稿するものを作ろうと思います, string-transformの変換元にShow aを追加しました
テストを書いたら本体のバグが発覚しました
hspecを使ってshouldThrow
を使っているのだけど,
意図した例外を送出してくれないのかdid not get expected exception
エラーになって困りました.
なんでだー??? と思って調べたら本体コードがバグっていることがわかりました. 非常に単純な変数の指定取り間違いでした… テストって大事ですね…
エラー時のレスポンスが捨てられてしまうのでhttpsJSONEitherは使わない
httpsJSONEither
を使うと,
aesonで指定していないJSONのフィールドがレスポンスから省略されてしまうためエラー表示がわかりにくいので,
あえてhttpsLBS
でデータを取得してJSONのパースはdecode
で行うように変更しました.
google検索した内容を「検索しました」とtwitterに投稿するwebアプリケーションを作ろうと思います
前から欲しいと思っていたwebサービスをいい加減実装するかと思ったけどそもそもwebサービスである必要性がわからなくなってきた. 内容はgoogle検索した内容を「検索しました」とtwitterに投稿するものです.
しかしこれ
- webアプリケーション
- ブラウザアドオン
- mikutterプラグイン
のどれでも実現可能なので, webアプリケーションとして実装するべきなのかな… と悩んでいます.
それ以前にプロダクトの名前を思いつかないので開発に着手できない. google-search-post-twitterは機能名そのまますぎるし長過ぎますね… アクロニムにしてgsptで良いか… と思ったらgithubにerikdubbelboer/gspt: setproctitle() for Goがあったのでやめよう.
tweet-when-searchなら長さも許容範囲内? でもtはtwitter検索, wはwikipedia検索, sはstackageに割り当ててるからどれも頭文字をインスタント検索の1文字に割り当てられないんですよねー pipe… と思ったけどpはpixivだった. なんか使える単語ないかなーと思ってtweetで検索したらintentが出てきた, iは使ってないのでintent-search-tweetで良いかな.
開発にあたってservantを使おうかと思いましたがログイン画面をサクサク作りたいので結局yesodになりそう…
string-transformの変換元にShow aを追加しました
このパッケージは基本的には文字列たちの変換をサポートするものですが,
他の言語のtoString
を考えると,
Int
などの非文字列も文字列化出来た方が嬉しいですね.
別に追加しない理由もありませんし.
と思って適当に
instance Show a => ToString a where
toString = show
してやったらエラー,
まあ予想していました.
例えばByteString
なんかはShow
のインスタンスなので,
上のByteString
だけに対するインスタンスか,
Show a => ToString a
のどちらを使えば良いのかわからなくなってしまいます.
OverlappingInstances
かIncoherentInstances
を使えばこの問題を回避できます.
インスタンス宣言と拡張機能 - #3(2009-12-03)
OverlappingInstances
は既に非推奨で,
いくつかのプラグマに分かれています.
とりあえずIncoherentInstances
を使ってみて解決しましたが,
インスタンスに[incoherent]
マークが付くんですね.
λ> :i ToString
class ToString a where
toString :: a -> String
{-# MINIMAL toString #-}
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:17:1
instance [incoherent] [safe] Show a => ToString a
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:35:10
instance [incoherent] [safe] ToString TL.Text
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:32:10
instance [incoherent] [safe] ToString T.Text
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:29:10
instance [incoherent] [safe] ToString BLU.ByteString
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:26:10
instance [incoherent] [safe] ToString BU.ByteString
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:23:10
instance [incoherent] [safe] ToString String
-- Defined at /mnt/data/repo/string-transform/src/Data/String/Transform.hs:20:10
OverlappingInstances
の分かれたプラグマを使うのと,
IncoherentInstances
を使うの,
どちらが良いのだろうか?
危険なもの
GHC の型検査器は時々、ある種の問題を解決できない時に、言語拡張を有効にするように何気なく教えてくれま> す。それらの中にはこれが含まれます。
- DatatypeContexts
- OverlappingInstances
- IncoherentInstances
- ImpredicativeTypes
これらはたいてい設計上の欠陥を暗に示しています。GHC が使うように提案しているとしても、エラーをその場> で解決するために頼るのはやめましょう!
そもそもこういう設計をすべきではなく,
show
はShow
に任せたほうが良いのかもしれない…
GHC/AdvancedOverlap - HaskellWikiを見るとclosed type familiesを使うという解決策もあるみたいですね. しかし, 今回は別に型レベルプログラミングをしているわけではないので, この方法は使えなさそうです.
IncoherentInstances
を使っていいのか悩みましたがそんなに使うなと怒っているページは見つかりませんでしたし,
safe haskellの範囲内で使えて普通に動くので使ってしまうことにしました.
追記
これByteString
がshowされたりしてめっちゃバグるので使ってはいけません。後からバージョン取り消したりして大変でした。