ユーザ定義三元演算子
12236 ワード
導入
三項演算子は非常に有用な構文表記法である
凝縮する意味.基本的に3つ
引数、そして構文的にそれは識別子です
つの部分に分割します.
例えば、
a ? b : c
a < b < c
a JOIN b ON c
initバイナリ演算子(ibo)を好むので、彼らは
容易に(または)呼ばれる
associativity ).
例えば、ほとんどの人は、AがBよりも読みやすく、理解しやすいと思います.
エー
B
a + b + c
(+ (+ a b) c)
なぜなら、IBOはとても重要だからです.Haskellのような最も機能的なプログラミング(FP)言語
カスタムIboを定義するユーザーを許可します.
例えば、
-- pipe forward operator
(|>) :: a -> (a -> b) -> b
a |> f = f a
-- example usage
main = [1, 2, 3]
|> map (+2)
|> filter (>3)
|> print
|> putStrLn -- [4, 5]
詳しく見るHaskell Infix Operator .バイナリ演算子のエミュレーション
しかし、ユーザ定義の三項演算子になると、
プログラミング言語のどれもメカニズムを提供しません.
三重演算子は、ダブルを使用してエミュレートできますが
Ibo、それはそれ自身の警告なしでありません.
テイクthis example Haskellから:
data Cond a = a :? a
infixl 0 ?
infixl 1 :?
(?) :: Bool -> Cond a -> a
True ? (x :? _) = x
False ? (_ :? y) = y
test = 1 < 2 ? "Yes" :? "No"
そのようなエミュレーションの警告は部分的な使用法です構文的に有効であるだけでなく、また
意味的に有効です.
例えば、我々はそれを省略することができます
:?
そして、コンパイラは文句を言わないでしょう.x = 1 < 2 ? "Yes"
ユーザーエクスペリエンス(UX)の観点から、これは非常に悪いです.ユーザーは常に使用するように意図したので
?
一緒に?:
.MixFix演算子を使用したエミュレート
Iboを使用する以外にも、MixFix演算子を使用して三項演算子をエミュレートできます.
例えば、Agda :
-- Example function name _if_else_
-- (emulating Python's conditional operator)
_if_else_ : {A : Set} -> Bool -> A -> A -> A
x if true else y = x
x if false else y = y
そのようなアプローチの警告は、ユーザが構文解析を行う前に構文を検索する必要があります
MixFix演算子で満たされたコードの一部.
例えば、上記
_if_else_
演算子は以下のように定義できます:if_then_else_ : {A : Set} -> Bool -> A -> A -> A
if x then true else y = x
if x then false else y = y
この場合、ユーザーは以下のコードを正確に解析することができませんif
またはelse
:x = a if b else c -- is this correct?
y = if a then b else c -- or this?
問題
前述の三成分乳濁液のために
演算子、私は許可するメカニズムを検索するための探求をしています
ユーザ定義の三項演算子です.
インスピレーション
私はしばらくの間、この質問を熟考しています
それでも、私が読むまで、重要な進歩はありません
ブックThe Relational Model of Database
Management
関係代数の発明者によって.Edgar. F. Codd .
シータジョンズを表すための彼の表記法は独創的です.
例えば、
SQL
エドガーの表記法
X join Y on A join Z on B
X [A] Y [B] Z
これについての独創的な部分は、彼が三項を扱うということです演算子としての演算子
上の例では、バイナリ演算子
[]
, is装飾された
A
, 違いを与える意味
これは実際にシータジョインの数学表記にも関する.
この場合、thethaシンボルは結合を飾っています
シンボルを返します.
バイナリ演算子として振る舞う.
このアプローチの利点は
演算子はバイナリ演算子のように振る舞う
彼らは自然に一緒にチェーンすることができます.
潜在的回答
三者演算子がちょうどある考えを拡大することによって
装飾された/汚染されたバイナリ演算子、私は最初にこの考えを持っています:
三項演算子は以下の構文で定義できます:
a X[ b ]Y c
どこa
, b
and c
は引数X[
and]Y
は三項演算子の名前です.たとえば、範囲チェックを定義しましょう.
-- Definition
a <[ b ]< c = a < b && b < c
-- Usage
print (1 <[2]< 3) -- true
print (1 <[3]< 2) -- false
仮定する[
]
の構文では使用されませんこのような三項演算子の使用法を解析することができます
簡単に.何故なら、ユーザーまたはマシンが
[
or]
, それから、彼らは三項演算子を予想することができます.しかしながら、上記の構文は明らかにあまりに騒がしいです
ノイズを減らす、我々は角括弧を交換することができます
[
]
, 最も目に見えないASCII演算子の一つで、バックチック.これにより、上記範囲チェックを次のように書き換えることができる.
-- Definition
a <` b `< c = a < b && b < c
-- Usage
print (1 <` 2 `< 3) -- true
print (1 <` 3 `< 2) -- true
したがって、三項演算子を定義するためにこれまでに考えられる最良の仕組みは次のとおりです.a X` b `Y c
-- Where a, b and c are the arguments
-- while X` and `Y together is the name of the ternary operator
優先順位についても、三項演算子は例えば、バイナリ演算子よりも優先順位が低い:
(a <` b + c `< d) MEANS (a <` (b + c) `< d)
関連性については左の連想性の上の正しい連想性
多くの場合、より一般的です.
したがって:
a X` b `Y c X` d `Y e = a X` b `Y (c X` d `Y e)
例えば、条件付き三項演算子true then` b `else c = b
false then` b `else c = c
ここでa then` b `else c then` d `else e
通常は(正しい連想)を意味する:a then` b `else (c then` d `else e)
(左の連想)(a then` b `else c) then` d `else e
結論
うまくいけば、この記事はあなたにインスピレーションを与えました
ユーザ定義三項演算子の機構
読書ありがとう.
Reference
この問題について(ユーザ定義三元演算子), 我々は、より多くの情報をここで見つけました https://dev.to/wongjiahau/user-defined-ternary-operator-453eテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol