"টাইপ বিযুক্তি" (ইউনিয়ন প্রকার) কীভাবে সংজ্ঞায়িত করবেন?


181

ওভারলোডেড পদ্ধতির ডাবল সংজ্ঞা নিয়ে কাজ করার পরামর্শ দেওয়া একটি উপায় হ'ল প্যাটার্ন মিলের সাথে ওভারলোডিং প্রতিস্থাপন:

object Bar {
   def foo(xs: Any*) = xs foreach { 
      case _:String => println("str")
      case _:Int => println("int")
      case _ => throw new UglyRuntimeException()
   }
}

এই পদ্ধতির প্রয়োজন হয় যে আমরা যুক্তিতে স্ট্যাটিক টাইপ চেকিং সমর্পণ করব foo। এটি লিখতে সক্ষম হতে আরও ভাল লাগবে

object Bar {
   def foo(xs: (String or Int)*) = xs foreach {
      case _: String => println("str")
      case _: Int => println("int")
   }
}

আমি এর সাথে কাছে যেতে পারি Eitherতবে এটি দু'রও বেশি ধরণের সাথে কুৎসিত দ্রুত হয়:

type or[L,R] = Either[L,R]

implicit def l2Or[L,R](l: L): L or R = Left(l)
implicit def r2Or[L,R](r: R): L or R = Right(r)

object Bar {
   def foo(xs: (String or Int)*) = xs foreach {
      case Left(l) => println("str")
      case Right(r) => println("int")
   }
}

এটা একটা সাধারণ (মার্জিত, দক্ষ) সমাধান করতে হবে সংজ্ঞায়িত মত দেখায় Either3, Either4একই শেষ অর্জনে একটি বিকল্প সমাধান, .... নেই কেউ কি জানেন? আমার জানা মতে, স্কালার অন্তর্নির্মিত "টাইপ বিযুক্তি" নেই। এছাড়াও, নিখুঁত রূপান্তরগুলি কি কোথাও প্রমিত লাইব্রেরিতে লুকিয়ে থাকা সংজ্ঞায়িত করা হয়েছে যাতে আমি কেবল সেগুলি আমদানি করতে পারি?

উত্তর:


142

ভাল, নির্দিষ্ট ক্ষেত্রে Any*, নীচের এই কৌশলটি কাজ করবে না, কারণ এটি মিশ্র প্রকারগুলি গ্রহণ করবে না। যাইহোক, যেহেতু মিশ্র প্রকারগুলি ওভারলোডিংয়ের সাথে কাজ করে না, এটি আপনার পছন্দ হতে পারে।

প্রথমে আপনি নীচের মত যে ধরণের গ্রহণ করতে চান তা দিয়ে একটি শ্রেণীর ঘোষণা করুন:

class StringOrInt[T]
object StringOrInt {
  implicit object IntWitness extends StringOrInt[Int]
  implicit object StringWitness extends StringOrInt[String]
}

এরপরে, এর fooমতো ঘোষণা করুন :

object Bar {
  def foo[T: StringOrInt](x: T) = x match {
    case _: String => println("str")
    case _: Int => println("int")
  }
}

এবং এটাই. আপনি কল করতে পারেন foo(5)বা foo("abc"), এবং এটি কার্যকর হবে, তবে চেষ্টা করুন foo(true)এবং এটি ব্যর্থ হবে। এটি তৈরি করে ক্লায়েন্ট কোডটি পাশাপাশি থাকতে পারে StringOrInt[Boolean], যদি না নীচে র্যান্ডাল দ্বারা উল্লিখিত না হয় তবে আপনি StringOrIntএকটি sealedক্লাস তৈরি করেন।

এটি কাজ করে কারণ এর T: StringOrIntঅর্থের একটি অন্তর্নিহিত প্যারামিটার রয়েছে StringOrInt[T], এবং স্কালা সেই ধরণের কাজের জন্য কোড জিজ্ঞাসা করতে কোড তৈরি করতে সেখানে কোনও ফলস্বর রয়েছে কিনা তা দেখতে কোনও প্রকারের সহকর্মী অবজেক্টগুলির ভিতরে দেখায়।


14
যদি class StringOrInt[T]তৈরি করা হয় sealed, তবে আপনি যে "ফুটো" উল্লেখ করেছেন ("অবশ্যই এটি ক্লায়েন্ট কোড দ্বারা StringOrInt[Boolean]" তৈরি করে পাশের পদক্ষেপে থাকতে পারে )) প্লাগ করা আছে, কমপক্ষে যদি StringOrIntতার নিজস্ব কোনও ফাইল থাকে res তারপরে সাক্ষী অবজেক্টগুলি অবশ্যই একই সূত্রে সংজ্ঞায়িত করা উচিত StringOrInt
র‌্যান্ডাল স্কুল্জ

3
আমি এই সমাধানটি কিছুটা সাধারণ করার চেষ্টা করেছি (নীচে উত্তর হিসাবে পোস্ট করা)। Eitherপদ্ধতির তুলনায় মূল ত্রুটিটি মনে হচ্ছে আমরা ম্যাচটি পরীক্ষা করার জন্য প্রচুর সংকলক সমর্থন হারিয়েছি।
অ্যারন নভস্ট্রাপ

সুন্দর কৌশল! যাইহোক, সিল করা ক্লাস সহ, আপনি এখনও ক্লায়েন্ট কোডে এটি নিষ্ক্রিয় করতে পারেন হয় একটি অন্তর্নির্মিত ভাল b = নতুন স্ট্রিংঅরআইন্ট [বুলিয়ান] কে ফাঁকে ফাঁকে ফাঁকে বা স্পষ্টভাবে foo (2.9) (নতুন স্ট্রিংঅরেন্ট [ডাবল]) কল করে। আমি মনে করি আপনার ক্লাসটি পাশাপাশি বিমূর্ত করা দরকার।
পাওলো ফালেবেলা

2
হ্যাঁ; এটি ব্যবহার করা সম্ভবত আরও ভাল হবেtrait StringOrInt ...
যান্ত্রিক শামুক

7
পিএস আপনি যদি সাব টাইপগুলি সমর্থন করতে চান তবে কেবল এতে পরিবর্তন StringOrInt[T]করুন StringOrInt[-T](দেখুন স্ট্যাকওভারফ্লো / সেকশনস / 24387701/… )
ইরান মেডান

178

মাইলস সাবিন তার সাম্প্রতিক ব্লগ পোস্টে ইউনিয়ন টাইপ করার জন্য ক্যালি-হাওয়ার্ড আইসোমর্ফিজমের মাধ্যমে স্কালায় আনবক্সড ইউনিয়ন প্রকারের জন্য খুব সুন্দর উপায় বর্ণনা করেছেন :

তিনি প্রথমে প্রকারের উপেক্ষাকে সংজ্ঞায়িত করেন

type ¬[A] = A => Nothing

ডি মরগানের আইন ব্যবহার করে এটি ইউনিয়নের ধরণের সংজ্ঞা দিতে পারে allows

type[T, U] = ¬[¬[T] with ¬[U]]

নিম্নলিখিত সহায়ক নির্মাণ সঙ্গে

type ¬¬[A] = ¬[¬[A]]
type ||[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) }

আপনি নিম্নলিখিত হিসাবে ইউনিয়ন প্রকার লিখতে পারেন:

def size[T : (Int || String)#λ](t : T) = t match {
    case i : Int => i
    case s : String => s.length
}

13
এটি আমি দেখেছি সবচেয়ে দুর্দান্ত বিষয়গুলির মধ্যে একটি।
সাবমনয়েড

18
এখানে মাইলসের ধারণার আমার বর্ধিত বাস্তবায়ন: github.com/GenslerAppsPod/scalavro/blob/master/util/src/main/… - উদাহরণ সহ: github.com/GenslerAppsPod/scalavro/blob/master/util/src/ পরীক্ষা /…
কনার ডয়েল

6
উপরের মন্তব্যটি নিজেই একটি উত্তর হওয়া উচিত। এটি মাইলসের ধারণার কেবল একটি বাস্তবায়ন, তবে ম্যাভেন সেন্ট্রালের একটি প্যাকেজে খুব সুন্দরভাবে আবৃত করা হয়েছে, এবং এই সমস্ত ইউনিকোড চিহ্ন ছাড়াই (?) কোথাও কোনও বিল্ড প্রক্রিয়াতে কোনও সমস্যা তৈরি করতে পারে।
জিম পিভারস্কি

2
সেই মজার চরিত্রটি বুলিয়ান অবহেলা
মিচিড

1
প্রথমদিকে, ধারণাটি আমার কাছে খুব দূষিত মনে হয়েছিল। এই থ্রেডে উল্লিখিত প্রায় প্রতিটি লিঙ্কটি পড়ে, আমি ধারণাটি এবং এর বাস্তবায়নের সৌন্দর্যে ধরা পড়েছিলাম: ... তবে আমি এখনও অনুভব করছি যে এটি কিছুটা বিশৃঙ্খলাযুক্ত ... এটি কেবলমাত্র সহজলভ্য নয় বলেই রয়েছে স্কেলা থেকে দূরে। মাইলস যেমন বলেছেন: "মার্টিন এবং অ্যাড্রায়ানকে সরাসরি অ্যাক্সেসযোগ্য করার জন্য এখন আমাদের কেবল পেস্টার প্রয়োজন" "
রিচার্ড গোমেস

44

ডটি , একটি নতুন পরীক্ষামূলক স্কালার সংকলক, ইউনিয়নের ধরণগুলি (লিখিত A | B) সমর্থন করে , তাই আপনি যা চান ঠিক তেমন করতে পারেন:

def foo(xs: (String | Int)*) = xs foreach {
   case _: String => println("str")
   case _: Int => println("int")
}

1
এই দিন গুলোর মধ্যে একটি.
মাইকেল আহ্লার্স

5
যাইহোক, ডট্টি হবে নতুন স্কেল 3 (এটি কয়েক মাস আগে ঘোষণা করা হয়েছিল)।
ইনফিনিটি 8

1
এবং 2020 এর শেষের দিকে কোথাও উপলভ্য হবে
জুলিয়েনডে

31

ইউনিয়নের প্রকারগুলি এনকোড করার জন্য এখানে রেক্স কেরার উপায়। সোজা ও সরল!

scala> def f[A](a: A)(implicit ev: (Int with String) <:< A) = a match {
     |   case i: Int => i + 1
     |   case s: String => s.length
     | }
f: [A](a: A)(implicit ev: <:<[Int with String,A])Int

scala> f(3)
res0: Int = 4

scala> f("hello")
res1: Int = 5

scala> f(9.2)
<console>:9: error: Cannot prove that Int with String <:< Double.
       f(9.2)
        ^

উত্স: মাইলস সাবিনের এই দুর্দান্ত ব্লগ পোস্টের অধীনে মন্তব্য # 27 , যা স্কালায় ইউনিয়ন প্রকারের এনকোডিংয়ের অন্য উপায় সরবরাহ করে।


6
দুর্ভাগ্যক্রমে, এই এনকোডিংটি পরাজিত হতে পারে: scala> f(9.2: AnyVal)টাইপচেকারকে পাস করে।
কিপটন ব্যারোস

@ কিপটন: দুঃখজনক। মাইলস সাবিনের এনকোডিংও কি এই সমস্যায় ভুগছে?
মিসিংফ্যাক্টর

9
মাইলসের কোডটির কিছুটা সহজ সংস্করণ রয়েছে; যেহেতু তিনি আসলে ফাংশনের বিপরীত প্যারামিটারের বিপরীত প্রভাব ব্যবহার করছেন, কঠোর "নয়" তাই আপনি trait Contra[-A] {}সমস্ত ফাংশনের জায়গায় কিছুতেই ব্যবহার করতে পারবেন না। সুতরাং আপনি type Union[A,B] = { type Check[Z] = Contra[Contra[Z]] <:< Contra[Contra[A] with Contra[B]] }ব্যবহারের মতো জিনিসগুলি def f[T: Union[Int, String]#Check](t: T) = t match { case i: Int => i; case s: String => s.length }(অভিনব ইউনিকোড ছাড়াই) পান।
রেক্স কের

এটি ইউনিয়নের ধরণের উত্তরাধিকারের সমস্যাটি সমাধান করতে পারে? stackoverflow.com/questions/45255270/...
jhegedus

হুম, আমি এটা চেষ্টা, আমি এই এনকোডিং সঙ্গে ফিরতি ধরনের তৈরি করতে পারবেন না, তাই তার subtyping বাস্তবায়ন সম্ভব হবে বলে মনে হচ্ছে না stackoverflow.com/questions/45255270/...
jhegedus

18

নিম্নলিখিত হিসাবে ড্যানিয়েলের সমাধানটি সাধারণীকরণ করা সম্ভব :

sealed trait Or[A, B]

object Or {
   implicit def a2Or[A,B](a: A) = new Or[A, B] {}
   implicit def b2Or[A,B](b: B) = new Or[A, B] {}
}

object Bar {
   def foo[T <% String Or Int](x: T) = x match {
     case _: String => println("str")
     case _: Int => println("int")
   }
}

এই পদ্ধতির প্রধান ত্রুটিগুলি হ'ল

  • ড্যানিয়েল যেমন উল্লেখ করেছেন, এটি মিশ্র প্রকারের সাথে সংগ্রহ / ভারার্গস পরিচালনা করে না
  • সংমিশ্রণটি সম্পূর্ণরূপে মেলা না হলে সংকলক সতর্কতা জারি করে না
  • ম্যাচটিতে একটি অসম্ভব কেস অন্তর্ভুক্ত থাকলে সংকলকটি একটি ত্রুটি জারি করে না
  • ভালো লেগেছে Eitherপদ্ধতির আরো সাধারণীকরণ সংজ্ঞা অনুরূপ করতে হবে Or3, Or4ইত্যাদি বৈশিষ্ট। অবশ্যই, এই জাতীয় বৈশিষ্ট্যগুলি সংজ্ঞায়িত করা সম্পর্কিত Eitherক্লাস সংজ্ঞার চেয়ে অনেক সহজ হবে be

হালনাগাদ:

মিচ ব্লিভিনস একটি খুব অনুরূপ পদ্ধতির প্রদর্শন করে এবং এটি "স্টুটারিং বা" ডাব করে কীভাবে এটি দুটিরও বেশি প্রকারে সাধারণীকরণ করবেন তা দেখায়।


17

আমি এই ধরণের মাইল সাবিনের কাজের সরলকরণের সাথে টাইপ তালিকার ধারণাকে একত্রিত করে এন-আরি ইউনিয়ন প্রকারের তুলনামূলকভাবে পরিষ্কার বাস্তবায়নে হোঁচট খেয়েছি , যার উত্তর অন্য কেউ উল্লেখ করেছেন।

প্রদত্ত প্রকার ¬[-A]যা বৈপরীত্যযুক্ত A, সংজ্ঞায়িত দ্বারা A <: Bআমরা লিখতে পারি ¬[B] <: ¬[A], প্রকারের ক্রমকে বিপরীত করে ।

প্রদত্ত প্রকারের A, Bএবং X, আমরা প্রকাশ করতে চাই X <: A || X <: B। বিপরীত প্রয়োগ, আমরা পেতে ¬[A] <: ¬[X] || ¬[B] <: ¬[X]। এটি পরিবর্তিত হিসাবে ¬[A] with ¬[B] <: ¬[X]কোনটি Aবা হিসাবে প্রকাশ করা যেতে পারেB একটি supertype হতে হবে Xবা Xনিজেই (ফাংশন আর্গুমেন্ট সম্পর্কে চিন্তা)।

object Union {
  import scala.language.higherKinds

  sealed trait ¬[-A]

  sealed trait TSet {
    type Compound[A]
    type Map[F[_]] <: TSet
  }

  sealed traitextends TSet {
    type Compound[A] = A
    type Map[F[_]] =}

  // Note that this type is left-associative for the sake of concision.
  sealed trait[T <: TSet, H] extends TSet {
    // Given a type of the form `∅ ∨ A ∨ B ∨ ...` and parameter `X`, we want to produce the type
    // `¬[A] with ¬[B] with ... <:< ¬[X]`.
    type Member[X] = T#Map[¬]#Compound[¬[H]] <:< ¬[X]

    // This could be generalized as a fold, but for concision we leave it as is.
    type Compound[A] = T#Compound[H with A]

    type Map[F[_]] = T#Map[F] ∨ F[H]
  }

  def foo[A : (∅ ∨ StringIntList[Int])#Member](a: A): String = a match {
    case s: String => "String"
    case i: Int => "Int"
    case l: List[_] => "List[Int]"
  }

  foo(42)
  foo("bar")
  foo(List(1, 2, 3))
  foo(42d) // error
  foo[Any](???) // error
}

হারাহা / আপTList এর ক্ষেত্রে যেমন দেখা যায় তেমনি সদস্যদের উপরের উপরের দিকের সাথে এই ধারণাটি একত্রিত করার চেষ্টা করার জন্য আমি কিছু সময় ব্যয় করেছি , তবে Mapটাইপ সীমাবদ্ধতার সাথে বাস্তবায়ন এতদূর চ্যালেঞ্জ প্রমাণিত হয়েছে।


1
এটি উজ্জ্বল, আপনাকে ধন্যবাদ! আমি আগের পদ্ধতির চেষ্টা করেছিলাম তবে ইউনিয়নের অংশ হিসাবে জেনেরিক ধরণের সাথে এটি ব্যবহার করার বিষয় ছিল। এটি ছিল একমাত্র বাস্তবায়ন যা আমি জেনেরিক ধরণের সাথে কাজ করতে পারি।
সমীর আদ্রা

দুঃখের বিষয়, তবে সম্ভবত আশা করা যায়, যখন আমি জাভা কোড থেকে ইউনিয়ন টাইপ করে এমন একটি স্কালা পদ্ধতি ব্যবহার করার চেষ্টা করি তখন এটি কার্যকর হয় না। ত্রুটি: (40, 29) জাভা: শ্রেণি কনফিগারেশনে পদ্ধতি সেটভ্যালু প্রদত্ত ধরণের ক্ষেত্রে প্রয়োগ করা যায় না; প্রয়োজনীয়: এক্স, স্কালা। প্রিডিফ $ কম $ কোলন $ কম <ইউনিয়ন টাইপস.প্যাকেজ। টাইপ-ভেরিয়েবল (গুলি) এক্স (প্রকৃত এবং আনুষ্ঠানিক যুক্তির তালিকাগুলি দৈর্ঘ্যের চেয়ে পৃথক)
সমের আদ্রা

এখনও এই বাস্তবায়নের কয়েকটি বিবরণ সম্পর্কে পুরোপুরি পরিষ্কার নয়। উদাহরণস্বরূপ, মূল নিবন্ধটি "টাইপ ¬ [এ] = এ => কিছুই না" হিসাবে অবজ্ঞাকে সংজ্ঞায়িত করেছে তবে এই সংস্করণটিতে যদি কেবল "সিলড বৈশিষ্ট্য ¬ [-A]" থাকে এবং বৈশিষ্ট্যটি কোথাও প্রসারিত হয় না। কিভাবে কাজ করে?
সমীর আদ্রা

@ সমর আদ্রা এটি যেভাবেই কাজ করবে, নিবন্ধটি Function1বিদ্যমান বিপরীত ধরণের হিসাবে ব্যবহার করে । আপনার কোনও প্রয়োগকরণের দরকার নেই, আপনার যা দরকার তা হ'ল কনফার্মেশন ( <:<) of
জে ক্র্যাকনেল

ইউনিয়ন টাইপ গ্রহণ করে এমন কনস্ট্রাক্টর কীভাবে থাকতে পারে তার কোনও ধারণা?
সমীর আদ্রা

12

একটি ধরণের শ্রেণীর সমাধান সম্ভবত এখানে যেতে সর্বোত্তম উপায়, ব্যবহারগুলি ব্যবহার করে। এটি ওডারস্কি / চামচ / ভেনার্স বইতে উল্লিখিত মনোয়েড পদ্ধতির অনুরূপ:

abstract class NameOf[T] {
  def get : String
}

implicit object NameOfStr extends NameOf[String] {
  def get = "str"
}

implicit object NameOfInt extends NameOf[Int] {
 def get = "int"
}

def printNameOf[T](t:T)(implicit name : NameOf[T]) = println(name.get)

আপনি যদি তবে এটি আরপিএলে চালান:

scala> printNameOf(1)
int

scala> printNameOf("sss")
str

scala> printNameOf(2.0f)
<console>:10: error: could not find implicit value for parameter nameOf: NameOf[
Float]
       printNameOf(2.0f)

              ^

আমি ভুল হতে পারি, তবে আমি মনে করি না যে এটি ওপি খুঁজছিল। ওপি একটি ডাটা টাইপ যা ধরনের অসংলগ্ন করা ইউনিয়ন প্রতিনিধিত্ব করতে পারে, এবং তারপর এটি কেস বিশ্লেষণ করতে তাকে জিজ্ঞাসা সম্পর্কে রানটাইম এ কি প্রকৃত টাইপ নিষ্কাশিত হতে দেখতে। টাইপ ক্লাসগুলি এই সমস্যাটি সমাধান করবে না, কারণ তারা খাঁটি সংকলন-সময় নির্মাণ।
টম ক্রকেট

4
বাস্তব প্রশ্ন জিজ্ঞাসা করা হচ্ছে কিভাবে বিভিন্ন ধরনের জন্য বিভিন্ন আচরণ প্রকাশ করার, কিন্তু ওভারলোডিং ব্যতীত ছিল। প্রকারের ক্লাসগুলির জ্ঞান ছাড়াই (এবং সম্ভবত সি / সি ++ এর কিছুটা এক্সপোজার) এক ইউনিয়ন ধরণের একমাত্র সমাধান বলে মনে হয়। স্কালার পূর্ব-বিদ্যমান Eitherপ্রকারটি এই বিশ্বাসকে আরও দৃforce় করে। স্কালার ফলস্বরূপ ধরণের শ্রেণীর ব্যবহার অন্তর্নিহিত সমস্যার আরও ভাল সমাধান, তবে এটি তুলনামূলকভাবে নতুন ধারণা এবং এখনও ব্যাপকভাবে জানা যায়নি, এ কারণেই ওপি তাদের ইউনিয়নের ধরণের সম্ভাব্য বিকল্প হিসাবে বিবেচনা করতেও জানতেন না।
কেভিন রাইট

এটি কি সাবটাইপিংয়ের সাথে কাজ করে? stackoverflow.com/questions/45255270/...
jhegedus

10

আমরা এমন একটি অপারেটর চাই Or[U,V]যা কোনও ধরণের পরামিতিগুলিকে Xএমনভাবে সীমাবদ্ধ করতে ব্যবহার করতে পারে যা হয় X <: Uবা হয় X <: V। এখানে আমরা একটি সংজ্ঞাটি পেতে পারি যতটা কাছাকাছি আসতে পারে:

trait Inv[-X]
type Or[U,T] = {
    type pf[X] = (Inv[U] with Inv[T]) <:< Inv[X]
}

এটি কীভাবে ব্যবহৃত হচ্ছে তা এখানে:

// use

class A; class B extends A; class C extends B

def foo[X : (B Or String)#pf] = {}

foo[B]      // OK
foo[C]      // OK
foo[String] // OK
foo[A]      // ERROR!
foo[Number] // ERROR!

এটি কয়েকটি স্কালা ধরণের কৌশল ব্যবহার করে। প্রধান এক হ'ল সাধারণীকরণযুক্ত ধরণের সীমাবদ্ধতা ব্যবহার । প্রদত্ত প্রকার Uএবং Vএবং স্কেল সংকলক একটি ক্লাস সরবরাহ করে U <:< V(এবং সেই শ্রেণীর একটি অন্তর্নিহিত বস্তু) যদি এবং কেবলমাত্র যদি স্কালা সংকলক প্রমাণ করতে পারে যে Uএটি একটি সাব টাইপ V। সাধারণ ধরণের প্রতিবন্ধকতা যা কিছু ক্ষেত্রে কাজ করে তা ব্যবহার করে এখানে একটি সরল উদাহরণ রয়েছে:

def foo[X](implicit ev : (B with String) <:< X) = {}

এই উদাহরণটিতে কাজ করে যখন Xক্লাসের একটা নিদর্শন B, একটি String, অথবা একটি টাইপ তন্ন তন্ন একটি supertype কিংবা একটি উপপ্রকার যে হয়েছে Bবা String। প্রথম দুটি ক্ষেত্রে, মূলশব্দটির সংজ্ঞা অনুসারে এটি সত্য withযে (B with String) <: Bএবং (B with String) <: Stringসুতরাং, স্কালা এমন একটি অন্তর্নিহিত অবজেক্ট সরবরাহ করবে যা এতে পাস করা হবে ev: স্কালা সংকলক সঠিকভাবে গ্রহণ করবে foo[B]এবংfoo[String]

শেষ ক্ষেত্রে, আমি এই সত্যের উপর নির্ভর করছি যে যদি U with V <: X, তবে U <: Xবা হয় V <: X। এটি স্বজ্ঞাতসুলভ সত্য বলে মনে হচ্ছে এবং আমি কেবল এটি ধরে নিচ্ছি। এটি এই অনুমান থেকেই স্পষ্ট হয় যে এই সরল উদাহরণটি কেন ব্যর্থ হয় যখন Xসুপারটাইপ বা হয় উভয়ের উপপ্রকার Bবা String: উদাহরণস্বরূপ, উপরের উদাহরণে foo[A]ভুলভাবে গৃহীত হয় এবং foo[C]ভুলভাবে প্রত্যাখ্যান করা হয়। আবার, কি আমরা চাই ভেরিয়েবল উপর টাইপ মত প্রকাশের কিছু ধরনের U, Vএবং Xযে ঠিক সত্য যখন X <: UবাX <: V

বিপরীতে স্কালার ধারণাটি এখানে সহায়তা করতে পারে। বৈশিষ্ট্য মনে আছে trait Inv[-X]? কারণ এটি এর ধরণের পরামিতিগুলিতে বিপরীত X, Inv[X] <: Inv[Y]যদি এবং কেবল যদি Y <: X। তার মানে হল যে আমরা উপরের উদাহরণটিকে বাস্তবে কাজ করবে এমন একটি দিয়ে প্রতিস্থাপন করতে পারি:

trait Inv[-X]
def foo[X](implicit ev : (Inv[B] with Inv[String]) <:< Inv[X]) = {}

এর এটা এ কারণে যে অভিব্যক্তি (Inv[U] with Inv[V]) <: Inv[X], সত্য, ঠিক যখন উপরে একই ধৃষ্টতা দ্বারা Inv[U] <: Inv[X]বা Inv[V] <: Inv[X], এবং contravariance সংজ্ঞা দ্বারা, এই সত্য ঠিক যখন X <: Uবা X <: V

প্যারামিট্রিজেবল টাইপ ঘোষণা BOrString[X]করে এবং নীচে এটি ব্যবহার করে জিনিসগুলিকে কিছুটা পুনরায় ব্যবহারযোগ্য করে তোলা সম্ভব :

trait Inv[-X]
type BOrString[X] = (Inv[B] with Inv[String]) <:< Inv[X]
def foo[X](implicit ev : BOrString[X]) = {}

Scala এখন টাইপ গঠন করা করার প্রচেষ্টা করা হবে BOrString[X]যে জন্য Xযে fooসঙ্গে বলা হয়, এবং ধরন অবিকল নির্মাণকাজ শেষ হবে কবে Xপারেন একটি উপপ্রকার হয় Bবা String। এটি কাজ করে, এবং একটি সংক্ষিপ্ত স্বরলিপি আছে। নীচের বাক্য গঠনটি সমতুল্য (এটি ব্যতীত evএখন implicitly[BOrString[X]]কেবল পদ্ধতিটির চেয়ে সহজ হিসাবে বর্ণিত হওয়া উচিত ev) এবং প্রকারের প্রসঙ্গে আবদ্ধBOrString হিসাবে ব্যবহার করা হয় :

def foo[X : BOrString] = {}

আমরা আসলে যা চাই তা হ'ল প্রকারের প্রসঙ্গের সীমাবদ্ধ তৈরি করার একটি নমনীয় উপায়। কোনও প্রকারের প্রসঙ্গটি অবশ্যই একটি প্যারামিট্রিজেবল প্রকারের হতে হবে এবং একটি তৈরি করার জন্য আমরা প্যারামিট্রাইজেবল উপায় চাই। মনে হচ্ছে আমরা যেমন ভ্যালুগুলিতে কারিগুলি তৈরি করতে চাই ঠিক তেমন ফাংশনগুলি কারি করার চেষ্টা করছি। অন্য কথায়, আমরা নিম্নলিখিতগুলির মতো কিছু চাই:

type Or[U,T][X] = (Inv[U] with Inv[T]) <:< Inv[X]

এটি স্ক্যালায় সরাসরি সম্ভব নয় , তবে এমন একটি কৌশল আছে যা আমরা ব্যবহার করতে পারি বেশ কাছাকাছি আসার জন্য। এটি আমাদের Orউপরের সংজ্ঞাটিতে নিয়ে আসে :

trait Inv[-X]
type Or[U,T] = {
    type pf[X] = (Inv[U] with Inv[T]) <:< Inv[X]
}

এখানে আমরা একটি কাঠামোগত টাইপ তৈরি করতে স্ট্রাকচারাল টাইপিং এবং স্কালার পাউন্ড অপারেটর ব্যবহার করি Or[U,T]যা একটি অভ্যন্তরীণ প্রকারের গ্যারান্টিযুক্ত। এটি একটি অদ্ভুত জন্তু। কিছু প্রসঙ্গ দিতে, ফাংশনটি def bar[X <: { type Y = Int }](x : X) = {}অবশ্যই তাদের সাবক্লাসের সাথে কল করতে হবে যা তাদের মধ্যে AnyRefএকটি প্রকারের Yসংজ্ঞা দেওয়া আছে:

bar(new AnyRef{ type Y = Int }) // works!

পাউন্ড অপারেটর ব্যবহার করে আমাদের অভ্যন্তরীণ প্রকারটি উল্লেখ করতে দেয় Or[B, String]#pfএবং প্রকার অপারেটরের জন্য ইনফিক্স নোটেশন ব্যবহার করে Orআমরা আমাদের মূল সংজ্ঞাটিতে পৌঁছে যাই foo:

def foo[X : (B Or String)#pf] = {}

বৈশিষ্ট্যটি সংজ্ঞায়িত না করার জন্য আমরা এই সত্যটি ব্যবহার করতে পারি যে ফাংশন প্রকারগুলি তাদের প্রথম ধরণের পরামিতিগুলিতে বিপরীত হয় Inv:

type Or[U,T] = {
    type pf[X] = ((U => _) with (T => _)) <:< (X => _)
} 

এটি কি A|B <: A|B|Cসমস্যার সমাধান করতে পারে? stackoverflow.com/questions/45255270/… আমি বলতে পারি না।
ঝেগেদুস

8

এটিও আছে হ্যাক :

implicit val x: Int = 0
def foo(a: List[Int])(implicit ignore: Int) { }

implicit val y = ""
def foo(a: List[String])(implicit ignore: String) { }

foo(1::2::Nil)
foo("a"::"b"::Nil)

ধরণের মুছে ফেলা অস্পষ্টতা (স্কালা) প্রায় কাজ করা দেখুন ।


স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 3422336/ … দেখুন । আসলে একটি সহজ হ্যাক রয়েছে: কেবল (implicit e: DummyImplicit)স্বাক্ষরগুলির মধ্যে একটিতে যুক্ত করুন ।
অ্যারন নভস্ট্রাপ

7

আপনি মেটাস্কালার দিকে একবার নজর দিতে পারেন , যার কাছে কিছু আছে OneOf। আমি এই ধারণাটি পেয়েছি যে এটি matchস্টেটমেন্টগুলির সাথে ভালভাবে কাজ করে না তবে আপনি উচ্চতর অর্ডার ফাংশনগুলি ব্যবহার করে ম্যাচটি অনুকরণ করতে পারেন। উদাহরণস্বরূপ, এই স্নিপেটটি একবার দেখুন , কিন্তু নোট করুন যে "সিমুলেটেড ম্যাচিং" অংশটি মন্তব্য করা হয়েছে, সম্ভবত এটি এখনও কার্যকর হয়নি।

এখন কিছু সম্পাদকীয় করার জন্য: আমি মনে করি না যে আপনি বর্ণিত হিসাবে Either3, Either4, ইত্যাদির সংজ্ঞায়িত করার মতো কিছু খারাপ কাজ আছে। এটি স্কালায় অন্তর্নির্মিত মানক 22 টি দ্বৈত প্রকারের মূলত দ্বৈত। এটি অবশ্যই দুর্দান্ত লাগবে যদি স্কালার অন্তর্নির্মিত বিভাজনযুক্ত ধরণের থাকে এবং তাদের পক্ষে সম্ভবত কিছু চমৎকার বাক্য গঠন রয়েছে {x, y, z}


6

আমি ভাবছি যে প্রথম শ্রেণির বিচ্ছিন্নতাটি হ'ল একটি সিলড সুপার টাইপ, বিকল্প সাব টাইপগুলি সহ এবং এই বিকল্প সাব-টাইপের সাথে কাঙ্ক্ষিত ধরণের সংশ্লেষের / থেকে অন্তর্নিহিত রূপান্তর।

আমি এই ঠিকানাগুলিতে মাইলস সাবিনের সমাধানের 33 - 36 মন্তব্য মন্তব্য করে ধরেছি , তাই ব্যবহারের সাইটে নিযুক্ত হতে পারে এমন প্রথম শ্রেণীর ধরণ, তবে আমি এটি পরীক্ষা করিনি।

sealed trait IntOrString
case class IntOfIntOrString( v:Int ) extends IntOrString
case class StringOfIntOrString( v:String ) extends IntOrString
implicit def IntToIntOfIntOrString( v:Int ) = new IntOfIntOrString(v)
implicit def StringToStringOfIntOrString( v:String ) = new StringOfIntOrString(v)

object Int {
   def unapply( t : IntOrString ) : Option[Int] = t match {
      case v : IntOfIntOrString => Some( v.v )
      case _ => None
   }
}

object String {
   def unapply( t : IntOrString ) : Option[String] = t match {
      case v : StringOfIntOrString => Some( v.v )
      case _ => None
   }
}

def size( t : IntOrString ) = t match {
    case Int(i) => i
    case String(s) => s.length
}

scala> size("test")
res0: Int = 4
scala> size(2)
res1: Int = 2

একটা সমস্যা Scala ক্ষেত্রে ম্যাচিং প্রেক্ষাপটে নিয়োগ করে না, থেকে একটি অন্তর্নিহিত রূপান্তর হবে IntOfIntOrStringথেকে Int(এবং StringOfIntOrStringকরতে String), তাই extractors এবং সংজ্ঞায়িত ব্যবহার করা আবশ্যক case Int(i)পরিবর্তে case i : Int


ADD: আমি মাইলস সাবিনকে তার ব্লগে নিম্নরূপ প্রতিক্রিয়া জানিয়েছি। সম্ভবত একাধিক উন্নতি হতে পারে:

  1. এটি ব্যবহার বা সংজ্ঞা সাইটে কোনও অতিরিক্ত শব্দ ছাড়াই এটি 2 টিরও বেশি প্রকারের মধ্যে প্রসারিত।
  2. যুক্তিগুলি স্পষ্টভাবে বক্স করা হয়, যেমন প্রয়োজন হয় না size(Left(2))বা size(Right("test"))
  3. প্যাটার্ন মিলের সিনট্যাক্স সুস্পষ্টভাবে আনবক্সড হয়।
  4. বক্সিং এবং আনবক্সিং জেভিএম হটস্পট দ্বারা অপ্টিমাইজ করা যেতে পারে।
  5. ভবিষ্যতের প্রথম শ্রেণীর ইউনিয়ন ধরণের সিনট্যাক্সটি এমনটি হতে পারে, যাতে মাইগ্রেশন সম্ভবত বিরামহীন হতে পারে? সম্ভবত ইউনিয়নের টাইপের নামের Vজন্য Or, উদাহরণস্বরূপ IntVString, ` Int |v| String`, ` Int or String`, বা আমার প্রিয় `এর পরিবর্তে ব্যবহার করা ভাল wouldInt|String ` এর `

আপডেট: উপরের প্যাটার্নটির জন্য বিযুক্তির যৌক্তিক অবহেলা অনুসরণ করা হয়েছে এবং আমি মাইলস সাবিনের ব্লগে একটি বিকল্প (এবং সম্ভবত আরও দরকারী) প্যাটার্ন যুক্ত করেছি

sealed trait `Int or String`
sealed trait `not an Int or String`
sealed trait `Int|String`[T,E]
case class `IntOf(Int|String)`( v:Int ) extends `Int|String`[Int,`Int or String`]
case class `StringOf(Int|String)`( v:String ) extends `Int|String`[String,`Int or String`]
case class `NotAn(Int|String)`[T]( v:T ) extends `Int|String`[T,`not an Int or String`]
implicit def `IntTo(IntOf(Int|String))`( v:Int ) = new `IntOf(Int|String)`(v)
implicit def `StringTo(StringOf(Int|String))`( v:String ) = new `StringOf(Int|String)`(v)
implicit def `AnyTo(NotAn(Int|String))`[T]( v:T ) = new `NotAn(Int|String)`[T](v)
def disjunction[T,E](x: `Int|String`[T,E])(implicit ev: E =:= `Int or String`) = x
def negationOfDisjunction[T,E](x: `Int|String`[T,E])(implicit ev: E =:= `not an Int or String`) = x

scala> disjunction(5)
res0: Int|String[Int,Int or String] = IntOf(Int|String)(5)

scala> disjunction("")
res1: Int|String[String,Int or String] = StringOf(Int|String)()

scala> disjunction(5.0)
error: could not find implicit value for parameter ev: =:=[not an Int or String,Int or String]
       disjunction(5.0)
                  ^

scala> negationOfDisjunction(5)
error: could not find implicit value for parameter ev: =:=[Int or String,not an Int or String]
       negationOfDisjunction(5)
                            ^

scala> negationOfDisjunction("")
error: could not find implicit value for parameter ev: =:=[Int or String,not an Int or String]
       negationOfDisjunction("")
                            ^
scala> negationOfDisjunction(5.0)
res5: Int|String[Double,not an Int or String] = NotAn(Int|String)(5.0)

অন্য আপডেট: মাইল সাবিনের সমাধানের 23 এবং 35 মন্তব্য সম্পর্কে , ব্যবহারের সাইটে ইউনিয়নের ধরণের ঘোষণার উপায় এখানে। নোট করুন এটি প্রথম স্তরের পরে আনবক্স করা হয়েছে, অর্থাত্ বিযুক্তির যে কোনও ধরণের কাছে এটি এক্সটেনসিবল হওয়ার সুবিধা রয়েছে , যেখানে Eitherনেস্টেড বক্সিং প্রয়োজন এবং আমার পূর্ববর্তী মন্তব্যে d১ দৃষ্টান্তটি এক্সটেনসিবল ছিল না। অন্য কথায়, একটি D[Int ∨ String](যেমন একটি উপ-প্রকার) এর জন্য নির্ধারিত হয় D[Int ∨ String ∨ Double]

type ¬[A] = (() => A) => A
type[T, U] = ¬[T] with ¬[U]
class D[-A](v: A) {
  def get[T](f: (() => T)) = v match {
    case x : ¬[T] => x(f)
  }
}
def size(t: D[IntString]) = t match {
  case x: D[¬[Int]] => x.get( () => 0 )
  case x: D[¬[String]] => x.get( () => "" )
  case x: D[¬[Double]] => x.get( () => 0.0 )
}
implicit def neg[A](x: A) = new D[¬[A]]( (f: (() => A)) => x )

scala> size(5)
res0: Any = 5

scala> size("")
error: type mismatch;
 found   : java.lang.String("")
 required: D[?[Int,String]]
       size("")
            ^

scala> size("hi" : D[¬[String]])
res2: Any = hi

scala> size(5.0 : D[¬[Double]])
error: type mismatch;
 found   : D[(() => Double) => Double]
 required: D[?[Int,String]]
       size(5.0 : D[?[Double]])
                ^

স্পষ্টতই স্কালার সংকলকটিতে তিনটি বাগ রয়েছে।

  1. গন্তব্য বিভাজনের ক্ষেত্রে এটি প্রথম প্রকারের পরে কোনও প্রকারের জন্য সঠিক অন্তর্নিহিত ফাংশনটি চয়ন করবে না।
  2. এটি D[¬[Double]]ম্যাচ থেকে কেস বাদ দেয় না ।

3।

scala> class D[-A](v: A) {
  def get[T](f: (() => T))(implicit e: A <:< ¬[T]) = v match {
    case x : ¬[T] => x(f)
  }
}
error: contravariant type A occurs in covariant position in
       type <:<[A,(() => T) => T] of value e
         def get[T](f: (() => T))(implicit e: A <:< ?[T]) = v match {
                                           ^

প্রাপ্তির পদ্ধতিটি ইনপুট ধরণের ক্ষেত্রে যথাযথভাবে সীমাবদ্ধ নয়, কারণ Aসংকলকটি সমকামী অবস্থানের ক্ষেত্রে অনুমতি দেবে না। একটি তর্ক করতে পারে যে এটি একটি বাগ কারণ আমরা চাই সমস্তই প্রমাণ, আমরা ফাংশনে প্রমাণটি অ্যাক্সেস করি না। এবং আমি পছন্দ না পরীক্ষা জন্য তৈরি case _মধ্যে getপদ্ধতি, তাই আমি একটি unbox হতো না Optionmatchমধ্যে size()


মার্চ 05, 2012: পূর্ববর্তী আপডেটের একটি উন্নতি প্রয়োজন। মাইলস সাবিনের সমাধান সাবটিপিংয়ের সাথে সঠিকভাবে কাজ করেছে।

type ¬[A] = A => Nothing
type[T, U] = ¬[T] with ¬[U]
class Super
class Sub extends Super

scala> implicitly[(SuperString) <:< ¬[Super]]
res0: <:<[?[Super,String],(Super) => Nothing] = 

scala> implicitly[(SuperString) <:< ¬[Sub]]
res2: <:<[?[Super,String],(Sub) => Nothing] = 

scala> implicitly[(SuperString) <:< ¬[Any]]
error: could not find implicit value for parameter
       e: <:<[?[Super,String],(Any) => Nothing]
       implicitly[(Super ? String) <:< ?[Any]]
                 ^

আমার পূর্বের আপডেটের প্রস্তাবনা (প্রথম শ্রেণীর ইউনিয়নের ধরণের কাছে) সাব-টাইপিং ভেঙেছে।

 scala> implicitly[D[¬[Sub]] <:< D[(SuperString)]]
error: could not find implicit value for parameter
       e: <:<[D[(() => Sub) => Sub],D[?[Super,String]]]
       implicitly[D[?[Sub]] <:< D[(Super ? String)]]
                 ^

সমস্যা হল Aমধ্যে(() => A) => A কোভেরিয়েন্ট (রিটার্ন টাইপ) এবং কনট্রোভারেন্ট (ফাংশন ইনপুট, বা এক্ষেত্রে ফাংশনের রিটার্ন ভ্যালু যা একটি ফাংশন ইনপুট) উভয় প্রদর্শিত হয়, সুতরাং প্রতিস্থাপনগুলি কেবল অদম্য হতে পারে।

লক্ষ্য করুন A => Nothingপ্রয়োজনীয় শুধুমাত্র কারণ আমরা চাই Acontravariant ভঙ্গিমায়, যাতে তিনি যে supertypes A নয় উপশাখাকে এর D[¬[A]]কিংবা D[¬[A] with ¬[U]]( তাও দেখতে )। যেহেতু আমাদের কেবল দ্বিগুণ বিরূপতা প্রয়োজন, আমরা মাইলস এর সমাধানের সমতুল্য অর্জন করতে পারি এমনকি যদি আমরা ¬এবং বাতিল করতে পারি

trait D[-A]

scala> implicitly[D[D[Super]] <:< D[D[Super] with D[String]]]
res0: <:<[D[D[Super]],D[D[Super] with D[String]]] = 

scala> implicitly[D[D[Sub]] <:< D[D[Super] with D[String]]]
res1: <:<[D[D[Sub]],D[D[Super] with D[String]]] = 

scala> implicitly[D[D[Any]] <:< D[D[Super] with D[String]]]
error: could not find implicit value for parameter
       e: <:<[D[D[Any]],D[D[Super] with D[String]]]
       implicitly[D[D[Any]] <:< D[D[Super] with D[String]]]
                 ^

সুতরাং সম্পূর্ণ ফিক্স হয়।

class D[-A] (v: A) {
  def get[T <: A] = v match {
    case x: T => x
  }
}

implicit def neg[A](x: A) = new D[D[A]]( new D[A](x) )

def size(t: D[D[Int] with D[String]]) = t match {
  case x: D[D[Int]] => x.get[D[Int]].get[Int]
  case x: D[D[String]] => x.get[D[String]].get[String]
  case x: D[D[Double]] => x.get[D[Double]].get[Double]
}

স্কালায় পূর্বের 2 বাগগুলি মনে রাখবেন, তবে 3 য়টি এড়িয়ে যাওয়া এড়ানো হয়েছে যেহেতু Tএখন এটির সাব-টাইপ হওয়া সীমাবদ্ধ A

আমরা সাব টাইপিংয়ের কাজগুলি নিশ্চিত করতে পারি।

def size(t: D[D[Super] with D[String]]) = t match {
  case x: D[D[Super]] => x.get[D[Super]].get[Super]
  case x: D[D[String]] => x.get[D[String]].get[String]
}

scala> size( new Super )
res7: Any = Super@1272e52

scala> size( new Sub )
res8: Any = Sub@1d941d7

আমি ভাবছিলাম যে প্রথম-শ্রেণীর ছেদগুলির ধরণগুলি অত্যন্ত গুরুত্বপূর্ণ, উভয় কারণে সিলোন রয়েছে এবং এটির পরিবর্তে যার অর্থ একটি প্রত্যাশিত ধরণের সাথে আনবক্সিং একটি রানটাইম ত্রুটি তৈরি করতে পারে , একটিটির আনবক্সিং (একটি ভিন্নধর্মী সংগ্রহ রয়েছে) ক) বিচ্ছিন্নতা যাচাই করে টাইপ করা যেতে পারে (স্ক্যালাগুলি আমি উল্লেখ করা বাগগুলি ঠিক করতে হবে)। ইউনিয়ন চেয়ে বেশি সহজবোধ্য হয় ব্যবহারের জটিলতা পরীক্ষামূলক HList এর metascala ভিন্নধর্মী সংগ্রহের জন্য।Anymatch


উপরের # 3 আইটেমটি স্কালা সংকলকটিতে কোনও বাগ নয় । দ্রষ্টব্য আমি মূলত এটি বাগ হিসাবে গণনা করি নি, তবে আজ অযত্নে একটি সম্পাদনা করে তা করেছি (এটি একটি বাগ হিসাবে উল্লেখ না করার জন্য আমার মূল কারণটি ভুলে গিয়ে)। আমি পোস্টটি আবার সম্পাদনা করিনি, কারণ আমি 7 সম্পাদনের সীমাতে আছি।
শেলবি মুর তৃতীয়


# 2 আইটেমটি কোনও বাগ নয়। স্কেলা সম্পূর্ণরূপে ইউনিয়নের ধরণ প্রকাশ করতে পারে না । লিঙ্কযুক্ত নথিটি কোডটির অন্য একটি সংস্করণ সরবরাহ করে, যাতে sizeআর D[Any]ইনপুট হিসাবে গ্রহণ না করে ।
শেলবি মুর III

আমি বেশ এই উত্তর পাবেন না, এই এই প্রশ্নের উত্তর হল: stackoverflow.com/questions/45255270/...
jhegedus

5

আর একটি উপায় আছে যা আপনি কারি-হাওয়ার্ডকে কুঁচকান না করে তা বোঝার জন্য কিছুটা সহজ:

type v[A,B] = Either[Option[A], Option[B]]

private def L[A,B](a: A): v[A,B] = Left(Some(a))
private def R[A,B](b: B): v[A,B] = Right(Some(b))  
// TODO: for more use scala macro to generate this for up to 22 types?
implicit def a2[A,B](a: A): v[A,B] = L(a)
implicit def b2[A,B](b: B): v[A,B] = R(b)
implicit def a3[A,B,C](a: A): v[v[A,B],C] = L(a2(a))
implicit def b3[A,B,C](b: B): v[v[A,B],C] = L(b2(b))
implicit def a4[A,B,C,D](a: A): v[v[v[A,B],C],D] = L(a3(a))
implicit def b4[A,B,C,D](b: B): v[v[v[A,B],C],D] = L(b3(b))    
implicit def a5[A,B,C,D,E](a: A): v[v[v[v[A,B],C],D],E] = L(a4(a))
implicit def b5[A,B,C,D,E](b: B): v[v[v[v[A,B],C],D],E] = L(b4(b))

type JsonPrimtives = (String v Int v Double)
type ValidJsonPrimitive[A] = A => JsonPrimtives

def test[A : ValidJsonPrimitive](x: A): A = x 

test("hi")
test(9)
// test(true)   // does not compile

আমি ডিজনেও একই জাতীয় কৌশল ব্যবহার করি


এটি কি সাব টাইপিং দিয়ে কাজ করতে পারে? আমার অন্ত্র অনুভূতি: না, তবে আমি ভুল হতে পারি। stackoverflow.com/questions/45255270/...
jhegedus

1

ঠিক আছে, এগুলি খুব চালাক, তবে আমি নিশ্চিত যে আপনি ইতিমধ্যে জানেন যে আপনার শীর্ষস্থানীয় প্রশ্নের উত্তরগুলি "ন" এর বিভিন্ন প্রকারের। স্কালা ওভারলোডিংকে অন্যরকমভাবে পরিচালনা করে এবং এটিকে অবশ্যই স্বীকার করা উচিত, আপনার বর্ণনার চেয়ে কিছুটা কম মার্জিতভাবে। এর কয়েকটি জাভা আন্তঃব্যবযোগিতার কারণে, এর কয়েকটি হ'ল ইনফেরেন্সিং অ্যালগরিদম ধরণের ক্ষেত্রে আঘাত করতে না চাওয়ার কারণে, এবং এর কয়েকটি হ্যাশেল না হওয়ার কারণে।


5
আমি যখন কিছুক্ষণ স্ক্যালাল ব্যবহার করছিলাম তখন আমি ততটা জ্ঞানী বা তত স্মার্ট নই যা আপনার মনে হয়। এই উদাহরণে, আমি দেখতে পাচ্ছি যে কোনও গ্রন্থাগার কীভাবে সমাধান সরবরাহ করতে পারে। এ জাতীয় লাইব্রেরিটি (বা কোনও বিকল্প) উপস্থিত রয়েছে কিনা তা অবাক করে দিয়ে বোঝা যায়।
অ্যারন নভস্ট্রাপ

1

এখানে ইতিমধ্যে দুর্দান্ত উত্তর যুক্ত করা হচ্ছে। মাইল সাবিন ইউনিয়নের ধরণগুলি (এবং জোশের ধারণাগুলি) নিয়ে তৈরি করে এমন একটি সংক্ষিপ্তসার এখানে দেওয়া হয়েছে তবে এগুলি পুনরাবৃত্তভাবে সংজ্ঞায়িত করা হয়েছে, যাতে আপনার> ইউনিয়নে> 2 প্রকার থাকতে পারে ( def foo[A : UNil Or Int Or String Or List[String])

https://gist.github.com/aishfenton/2bb3bfa12e0321acfc904a71dda9bfbb

এনবি: আমার যুক্ত করা উচিত যে কোনও প্রকল্পের জন্য উপরের সাথে খেলা করার পরে আমি সমতল-পুরাতন-সম-প্রকারগুলিতে ফিরে এসেছি (অর্থাত সাবক্লাস সহ সিলযুক্ত বৈশিষ্ট্য)। মাইলস সাবিন ইউনিয়নের ধরণগুলি টাইপ প্যারামিটারকে সীমাবদ্ধ করার জন্য দুর্দান্ত তবে আপনি যদি ইউনিয়নের প্রকারটি ফেরত নিতে চান তবে এটি খুব বেশি প্রস্তাব দেয় না।


এটি কি A|C <: A|B|Cসাব টাইপিং সমস্যা সমাধান করতে পারে ? stackoverflow.com/questions/45255270/... আমার অন্ত্রে অনুভূতি কোন কারণ তারপর, এটা অর্থ দাঁড়ায় এই যে A or Cউপপ্রকার হতে হবে (A or B) or Cকিন্তু যে টাইপ নেই A or Cতাই তৈরীর কোনো আশা নেই A or Cএকটি উপপ্রকার A or B or Cঅন্তত এই এনকোডিং এর সাথে .. . আপনি কি মনে করেন ?
ঝেগেদুস

0

থেকে ডক্স , যোগে সঙ্গে sealed:

sealed class Expr
case class Var   (x: String)          extends Expr
case class Apply (f: Expr, e: Expr)   extends Expr
case class Lambda(x: String, e: Expr) extends Expr

sealedঅংশ সম্পর্কে :

প্রোগ্রামের অন্যান্য অংশগুলিতে এক্সপ্রেস প্রসারিত আরও কেস ক্লাসগুলি সংজ্ঞায়িত করা সম্ভব (...)। এই শ্রেণীর এক্সটেনসিবিলিটি বেস ক্লাস এক্সপ্রেস সিল ঘোষিত করে বাদ দেওয়া যেতে পারে; এই ক্ষেত্রে, Expr সরাসরি প্রসারিত সমস্ত ক্লাস অবশ্যই Expr এর মতো একই উত্স ফাইলে থাকতে হবে as

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