[過去ログ] 関数型プログラミング言語Haskell Part33 (1002レス)
前次1-
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
900: 2021/09/22(水)10:43 ID:02VLVXq+(1/4) AAS
パターンの質問です

Rational型の数が平方数であるかどうか判定するプログラムで

isSquare r = r >= 0 && r == ( sqrtR r )^2
sqrtI = truncate . sqrt . fromInteger
sqrtR r = let
( a, b ) = ( numerator r, denominator r )
in ( sqrtI a ) % ( sqrtI b )

というのを書きました
もちろんこれはうまくいきます

しかし numerator, denominator をいちいち取り出すのが鬱陶しいので

sqrtR ( a :% b ) = ( sqrtI a ) % ( sqrtI b ) ------- ?

と書きたかったのですがうまくいきません
901: 2021/09/22(水)10:44 ID:02VLVXq+(2/4) AAS
ネットで調べると

{-# LANGUAGE PatternSynonyms, ViewPatterns #-}

numDenum :: Integral a => Ratio a -> (a,a)
numDenum x = ( numerator x, denominator x )

pattern ( :% ) :: Integral a => a -> a -> Ratio a
pattern a :% b <- ( numDenum -> ( a,b ) )
where a :% b = a % b

というおまじないがstack exchangeで見つかってコレつけるとうまく行きました
うまくいったんですがサッパリわかりません
コレ何者ですか?
そもそも?はなんでうまく動かないんですか?
903: 2021/09/22(水)18:38 ID:02VLVXq+(3/4) AAS
>>902
レスありがとうございます
原因わかりました
ご指摘の通り「計算結果にはパターンマッチさせられない、パターンマッチに入っていい関数はコンストラクタのみ」なのでRatio a型のコンストラクタである( :% )を使ってたのでそこは問題ないと思ってたんですが肝腎要の( :% )が定義されてるGHC.Realをimportしてませんでした
Data.Ratioをimportしたら自動的に(:%)も使えるもんだと思い込んでいました
Pattern synonymsについては

外部リンク:qiita.com

でちょっと理解できました、が、そもそも使わなくても良くなりました
ご協力感謝です
904
(1): 2021/09/22(水)20:18 ID:02VLVXq+(4/4) AAS
備忘録がてら調べてわかった事書いておきます
Pattern Synonyms は今回のようにライブラリの提供者が型のコンストラクタを提供してない、しかしパターンマッチは使いたいとかの場合に使える拡張のようです
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
を使うと

pattern ( マッチさせたい表現) <-
( その型から取り出したい値を取り出す関数)
-> ( 取り出した値にマッチさせるパターン) )
( where さらにコンストラクタシノニムとしても使いたい場合の逆変換関数 )

の形で使うようです
例えばInt型でxが偶数であった場合にdiv x 2をパターンマッチで拾うために

pattern TwiceOf x <-
( ( \t -> ( div t 2 , even t ) ) -> ( x, True ) )

のように定義しておいて

main = do
case 2 of { DoubleOf x -> print x; _ -> print "odd" }
case 3 of { DoubleOf x -> print x; _ -> print "odd" }

のように利用できるようです
TwiceOf はあくまでパターンマッチの表現のみで使える“仮の”コンストラクタですがpattern文にwhere句を

pattern DoubleOf x <-
( ( \t -> ( div t 2 , even t ) ) -> ( x, True ) )
where TwiceOf x = 2*x

のように追加するとあたかもInt型の新しいコンストラクタが追加されたように振る舞い“DoubleOf 2”のような表現が許されるようになるようです
今回の場合はどうすべきか悩みどころです
ライブラリの開発者が低レベルの(:%)を公開しない理由もわかるので無理クリ(:%)を使うのもどうなんつて気もするし、かと言ってまだHaskellの標準として認められてない、GHCでしか使えない拡張使うのもどうなんという気もするし
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.034s