型クラス
Preludeの関数と、ByteStringの関数は、名前と機能が重複してるものが大量にあるのだけど、普通に両方使おうとすると
Prelude> :m + Data.ByteString Prelude Data.ByteString> :t length <interactive>:1:0: Ambiguous occurrence `length' It could refer to either `length', imported from Prelude or `length', imported from Data.ByteString Prelude Data.ByteString> :t Data.ByteString.length Data.ByteString.length :: ByteString -> Int Prelude Data.ByteString> :t Prelude.length Prelude.length :: [a] -> Int
とかなってうざい件。
This module is intended to be imported qualified, to avoid name clashes with Prelude functions. eg. import qualified Data.ByteString as B
と書いてあるけど、両者のアルゴリズムはしばしば共通して使えるんでないのかな〜という気がするので(例えば、あまり意味はないけど、getContents>>=putStrとか)、B.lengthとlengthを区別せずに済む方法があればいいのにと思う。
で、型クラス使えばいいような気がして
{-# OPTIONS -fglasgow-exts #-} module Container where import Data.Word import qualified Data.ByteString as S import Data.ByteString hiding (length,map,null) import qualified Prelude as P import Prelude hiding (length,map,null) class Container s a where length :: s -> Int map :: (a -> a) -> s -> s instance Container [t] t where length = P.length map = P.map instance Container ByteString Word8 where length = S.length map = S.map
とか書いてみたんだけど
*Container> length [1,2,3] <interactive>:1:0: No instance for (Container [t] a) arising from use of `length' at <interactive>:1:0-13 Possible fix: add an instance declaration for (Container [t] a) In the expression: length [1, 2, 3] In the definition of `it': it = length [1, 2, 3]
しょぼーん(´・ω・`)こういうの何とかなんないかな〜。後付けで、こういう拡張をしたいという状況はしばしばあると思うんだけど
どーでもいいけど、型クラスって普段あんまり自分で型クラス定義したりしないような。それとも、みんなバリバリ定義してるんだろうか。