এর মতো টার্নারি অপারেটর?:


94

আমি এই জাতীয় নির্মাণ এড়াতে চেষ্টা করছি:

val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result

ঠিক আছে, এই উদাহরণে thenএবং elseশাখাটি সহজ, তবে আপনি জটিলগুলি চিত্র করতে পারেন। আমি নিম্নলিখিত নির্মিত:

object TernaryOp {
  class Ternary[T](t: T) {
    def is[R](bte: BranchThenElse[T,R]) = if (bte.branch(t)) bte.then(t) else bte.elze(t)
  }
  class Branch[T](branch: T => Boolean) {
    def ?[R] (then: T => R) = new BranchThen(branch,then)
  }
  class BranchThen[T,R](val branch: T => Boolean, val then: T => R)
  class Elze[T,R](elze: T => R) {
    def :: (bt: BranchThen[T,R]) = new BranchThenElse(bt.branch,bt.then,elze)
  }
  class BranchThenElse[T,R](val branch: T => Boolean, val then: T => R, val elze: T => R)
  implicit def any2Ternary[T](t: T) = new Ternary(t)
  implicit def fct2Branch[T](branch: T => Boolean) = new Branch(branch)
  implicit def fct2Elze[T,R](elze: T => R) = new Elze(elze)
}

এটি সংজ্ঞায়িত করা হয়েছে, আমি উপরের সাধারণ উদাহরণটি এর সাথে প্রতিস্থাপন করতে পারি:

this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}

তবে কীভাবে আমি এ থেকে মুক্তি পাব s: String =>? আমি এরকম কিছু চাই:

this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}

আমি অনুমান করি যে সংকলকটির ধরণের অনুমানের জন্য অতিরিক্ত স্টাফ দরকার needs


যেহেতু আমার জবাবটি আসলে আমার কাছে নেই - কারণ আপনার সমস্যার কারণ হ'ল টাইপ অনুমানটি বাম থেকে ডানে সবচেয়ে ভাল কাজ করে তবে অপারেটর নজিরের কারণে আপনি আপনার টোকেনকে ডান থেকে বামে একসাথে আবদ্ধ করছেন। আপনি যদি আপনার সমস্ত বিবৃতি শব্দের (একই নজির সহ) তৈরি করেন এবং জিনিসগুলিকে একসাথে ভাগ করার উপায় পরিবর্তন করেন তবে আপনি যে পছন্দটি চান তা পেয়ে যাবেন। (অর্থাত আপনি করতেন HasIs, IsWithCondition, ConditionAndTrueCaseক্লাস মত প্রকাশের অংশের গড়তে হবে বাঁ দিক থেকে ডানদিকে।)
রেক্স কের

আমি অজ্ঞানভাবে বাম থেকে ডান দিকে প্রকারের অনুক্রমের পদ্ধতিটি অনুমান করেছিলাম, তবে পদ্ধতি নামগুলির অপারেটর প্রাধান্য এবং সাহচর্যতার সাথে জড়িত হয়েছি, বিশেষত ?অন্য কোনও আলফানাম চরের আগে একটি পদ্ধতির নাম প্রথম চর এবং :বাম সাহসিকতার জন্য একটি হিসাবে শুরু করে । বাম থেকে ডানে টাইপ অনুক্রমটি পেতে আমাকে নতুন পদ্ধতির নামগুলি নিয়ে পুনরায় চিন্তা করতে হবে। ধন্যবাদ!
পিটার স্মিটজ

উত্তর:


28

আমরা একত্রিত করতে পারি স্কালায় একটি টার্নারি অপারেটর কীভাবে সংজ্ঞায়িত করব যা নেতৃস্থানীয় টোকেন সংরক্ষণ করে? উত্তরের সাথে উত্তরটি কী কোনও মানকে একটি ভাল প্যাটার্ন মোড়ানো? পেতে

scala>   "Hi".getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res0: String = String

scala> List.getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res1: String = List

এটি কি আপনার প্রয়োজনের জন্য পর্যাপ্ত?


আমার মনে যা আছে তা খুব কাছে। সুন্দর পদ্ধতির আমি এটি সম্পর্কে ভাবেন। আমার প্রথম কোডটি এড়ানোর কারণ হ'ল valনিম্নলিখিত- ifবিভাগের জন্য অস্থায়ী না থাকার ক্ষেত্রে আরও সংক্ষিপ্ত হওয়া ছিল : এটি যে মনে রাখবেন ঠিক তেমনই এটি একটি লাইনেও বোধগম্য হয়।
পিটার স্মিটজ

125

থেকে টনি মরিস 'ল্যামডা ব্লগ :

আমি এই প্রশ্নটি অনেক শুনেছি। হ্যাঁ এটা করে. পরিবর্তে c ? p : q, এটি লেখা হয় if(c) p else q

এটি পছন্দনীয় নাও হতে পারে। সম্ভবত আপনি জাভা হিসাবে একই সিনট্যাক্স ব্যবহার করে এটি লিখতে চাই। দুঃখের বিষয়, আপনি পারবেন না। এটি :বৈধ সনাক্তকারী নয় কারণ এটি This ভয় নেই, |হয়! আপনি কি এই জন্য নিষ্পত্তি করবেন?

c ? p | q

তারপরে আপনার নীচের কোডটি প্রয়োজন। =>আর্গুমেন্টে কল-বাই-নাম ( ) টীকা লক্ষ্য করুন। এই মূল্যায়নের কৌশলটি জাভারার টেরিনারি অপারেটরকে সঠিকভাবে পুনরায় লেখার জন্য প্রয়োজন। এটি নিজেই জাভাতে করা যায় না।

case class Bool(b: Boolean) {   
  def ?[X](t: => X) = new {
    def |(f: => X) = if(b) t else f   
  } 
}

object Bool {   
  implicit def BooleanBool(b: Boolean) = Bool(b) 
}

নতুন অপারেটরটি ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হয়েছে যা আমরা কেবল সংজ্ঞায়িত করেছি:

object T {   val condition = true

  import Bool._

  // yay!   
  val x = condition ? "yes" | "no"
}

আনন্দ কর ;)


হ্যাঁ, আমি এটি আগেও দেখেছি, তবে পার্থক্যটি হ'ল একটিতে আমার প্রথম অভিব্যক্তিটির (মূল্যায়ন) মান thenএবং elseধারাটিতে যুক্তি হিসাবে রয়েছে ।
পিটার স্মিটজ

4
আমি এই if(c) p else qপদ্ধতিটি গ্রহণ করেছি ... ধনুর্বন্ধের অভাব আমাকে একটি
স্পর্শকে

17

রেক্স কেরের উত্তর মৌলিক স্কেলে প্রকাশিত:

"Hi".getClass.getSimpleName match {
  case x if x.endsWith("$") => x.init
  case x => x
}

যদিও আমি নিশ্চিত নই যে এর কোন অংশটি ruct অন্যটি নির্মাণ করুন আপনি অনুকূল করতে চান।


খুব সোজা উপায়। কখনও কখনও কেউ প্রতিদিনের ব্যবহারের ম্যাচ / কেস স্টেটমেন্ট সম্পর্কে ভুলে যায়। আমি কেবল এক লাইনের ত্রিনিয়ী if then elseপ্রতিমাগুলিকে আঁকড়ে ধরেছি তবে এটি সমাধান করার পক্ষে এটি একটি বোধগম্য উপায়।
পিটার স্মিটজ

4
প্যাটার্ন ম্যাচিংয়ের জন্য দুটিরও বেশি শাখায় সহজে স্কেল।
রাফেল


0

যেহেতু: আপনি নিজের পিছনে টিক্স দিয়ে সর্বদা পলায়ন করতে ঠিক না হলে নিজেই বৈধ অপারেটর হবেন না :, আপনি অন্য একটি চরিত্রের সাথে যেতে পারেন, যেমন "|" উপরের উত্তরগুলির মধ্যে একটি হিসাবে। তবে একজন ছাগলের সাথে এলভিস সম্পর্কে কীভাবে? ::

implicit class Question[T](predicate: => Boolean) {
  def ?(left: => T) = predicate -> left
}
implicit class Colon[R](right: => R) {
  def ::[L <% R](pair: (Boolean, L)): R = if (q._1) q._2 else right
}
val x = (5 % 2 == 0) ? 5 :: 4.5

অবশ্যই আপনি যদি তালিকাভুক্ত হন তবে এটি আবার কাজ করবে না, যেহেতু তাদের নিজস্ব :: অপারেটর রয়েছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.