"মেজর সি" এর পরিবর্তে "সি মেজর" লেখার কোনও সুযোগ আছে কি?


39

আমি আমার সংগীত প্রকল্পে একটি ছোট্ট নান্দনিক সমস্যার মুখোমুখি হয়েছি এবং এটি কিছু সময়ের জন্য আমাকে বগল করছে।

আমার একটি টাইপ আছে data Key = C | D | ...এবং আমি Scaleএকটি Keyএবং এ থেকে একটি তৈরি করতে পারি ModeModeএকটি প্রধান এবং একটি ছোটখাট স্কেল যেমন মধ্যে আলাদা।

আমি বর্ণনা করতে পারেন Modeথেকে একটি ফাংশন হিসাবে টাইপ Keyকরতে Scale। সেক্ষেত্রে মোডগুলির ছোট হাতের নাম থাকবে (যা ভাল) এবং আমি এর মতো একটি স্কেল পেতে পারি

aScale = major C

তবে সংগীতজ্ঞরা এ জাতীয় কথা বলেন না। তারা এই স্কেলটিকে সি বড় স্কেল হিসাবে উল্লেখ করে , প্রধান সি স্কেল নয়।

আমি যা চাই

আদর্শভাবে আমি লিখতে চাই

aScale = C major

এটা কি আদৌ সম্ভব?

আমি কি চেষ্টা করেছি

আমি Keyএকটি ফাংশন তৈরি করতে পারি যা একটি Scaleথেকে একটি তৈরি করে Mode, তাই আমি লিখতে পারি

aScale = c Major

তবে আমি কীগুলি স্কেলগুলি তৈরির মধ্যে সীমাবদ্ধ রাখতে পারি না। এগুলি অন্যান্য জিনিসের জন্যও প্রয়োজন (যেমন জমিগুলি তৈরি করা )। এর Keyউদাহরণও হওয়া উচিত Show


আমি যখন কোনও অতিরিক্ত ফাংশন (বা মান নির্মাতা) ব্যবহার করি তার Modeপরে আমি এটি রাখতে Keyপারি:

aScale = scale C major সঙ্গে scale :: Key -> Mode -> Scale

তবে অতিরিক্ত শব্দ স্কেলটি গোলমাল এবং এর নামের সাথে বিপরীত দেখায়, scaleআঁশের সাথে সত্যই উদ্বিগ্ন নয়। বুদ্ধিমান অংশটি রয়েছে major, scaleসত্যই সঠিক flip ($)


আরও বুদ্ধিমান হওয়ার প্রয়োজন newtype Mode = Major | Minor ...ব্যতীত একটি ব্যবহারের ফলে খুব বেশি পরিবর্তন হয় না scale:

aScale = scale C Major

3
আমি নিজেকে অতীতে অত্যন্ত অনুরূপ সিনট্যাক্স চেয়েছি দেখেছি, তবে টিবিএইচ এটি লাভজনক নয়। শুধু সাথে যান major C
বাম দিকের বাইরে

4
ঠিক যেমন একটি মিউজিকাল কোয়েবল: "কী" হ'ল সেই ডেটাটাইপের জন্য একটি বিভ্রান্তিমূলক নাম, যেমন সি মেজর এবং সি মাইনর স্ট্যান্ডার্ড টার্মলজির বিভিন্ন কী। "পিচক্লাস" টাইপটির জন্য আরও সঠিক নাম হবে।
পিএলএল

2
@ পিএলএল প্রকৃতপক্ষে, সি, সি #, ডি এর জন্য একটি ভাল নাম খুঁজতে আমার সমস্যা হচ্ছে ... আমি জানি ইউটারপিয়া পিচক্লাস ব্যবহার করে। এটি কী-এর চেয়ে বেশি সঠিক তবে "সংগীত" মোটেও নয়। এই মুহুর্তে আমি এটিকে রুট বা টোনিক বলার ধারণার সাথে খেলছি যদিও এটি কেবল চির্ডস এবং স্কেলগুলিই প্রস্তাব করে। মিউজিশিয়ানরা সেই জিনিসটিকে কী বলে? অষ্টকভে ছাড়াই একটি নোট?
মার্টিন ড্রটজবার্গ

4
@ মার্টিনড্রাটজবার্গ: আমি বলব না যে পিচ ক্লাসটি আন-বাদ্যযন্ত্র - এটি কোনওভাবেই প্রোগ্রামার-বক্তৃতা নয়, এটি কমপক্ষে 20 শতকের মাঝামাঝি থেকে প্রায় "সংগীত তত্ত্ব" অর্থ "অষ্টক ছাড়া একটি নোট" হিসাবে প্রতিষ্ঠিত হয়েছে। এটি প্রযুক্তিগত সংগীত-তত্ত্বের প্রসঙ্গে খুব বেশি সাধারণ নয়, তবে এটি কেবলমাত্র "পিচ" এবং "অষ্টভর্তি একটি পিচ" এর মধ্যে সুনির্দিষ্ট পার্থক্যটি প্রতিদিনের ব্যবহারে প্রায়শই প্রয়োজন হয় না এবং যখন এটি প্রয়োজন হয় তখন এটি সাধারণত স্পষ্ট হয় প্রসঙ্গ থেকে। তবে "রুট" বা "টোনিক" শব্দটি কম সুনির্দিষ্টভাবে বলা হলে কিছুটা বেশি পরিচিত শব্দ হিসাবে ভাল লাগছে।
পিএলএল

1
না কারণ এটি বিপরীতে কাজ করে না, একটি প্রোগ্রামার
গানে

উত্তর:


29

সমাধান 1:

এটা ব্যবহার কর

data Mode  = Major | Minor
data Scale = C Mode | D Mode | E Mode | F Mode | G Mode | A Mode | B Mode 

এখন আপনি লিখতে পারেন (মূলধন সি এবং মূলধন এম সহ)

aScale = C Major

সমাধান 2 এ:

এটিও সম্ভব

data Mode  = Major | Minor
data Key   = C | D | E | F | G | A | B 

data Scale = Scale Key Mode  

এখন আপনি লিখুন

aScale = Scale C Major

সমাধান 2 বি:

এটিও সম্ভব

data Mode  = Major | Minor
data Key   = C | D | E | F | G | A | B 

type Scale = (Key, Mode)  

এখন আপনি লিখুন

aScale = (C, Major)

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

16

এখানে একটি তাত্পর্যপূর্ণ সমাধান যা আমি সত্যিই সুপারিশ করি না তবে দেখতে খুব "বাদ্যযন্ত্র":

infix 8 
(♮) :: Key -> Mode -> Scale
(♮) = (Data.Function.&)
 -- ≡ flip ($)

তাহলে আপনি লিখতে পারেন

> C major :: Scale

অবশ্যই, যেখানে এটি সত্যিই লক্ষ্যযুক্ত তা হ'ল আপনারও F♯ minorএবং B♭ majorইত্যাদি থাকবে ..


1
আমি ভাবছি সেখানে অবিচ্ছিন্ন স্পেস মত কিছু একটি অপারেটর হিসাবে :) অনুমোদিত যদি
chepner

26
@ চেপারার আসলে হ্যাঁ: ইউ + ২৮০০ ব্রায়েল প্যাটার্ন ব্ল্যাক ইনফিক্স হিসাবে ব্যবহার করা যেতে পারে। বলা বাহুল্য, এটি একটি ভয়াবহ ধারণা ... সমস্ত আসল স্থানের অক্ষরগুলিকে ইনফিক্স হিসাবে নিষিদ্ধ করা হয়েছে তবে অবাক হওয়ার মতো বিষয় ইউনিকোডে এমন কিছু রয়েছে যা অপব্যবহারের উদ্দেশ্যে হ্যাক করা যেতে পারে।
বাম দিকের বাইরে

11

আপনি যদি অতিরিক্ত অপারেটরটিকে কিছু মনে করেন না, আপনি এটি &থেকে ব্যবহার করতে পারেন Data.Function। ধরে নিই যে majorএটি একটি ফাংশন Key -> Scale, আপনি লিখতে পারেন C & major। এটি একটি Scaleমান উত্পাদন করে :

Prelude Data.Function> :t C & major
C & major :: Scale

4

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

কিছু সমস্যা ডোমেন প্রকারের জন্য স্ট্যান্ডার্ড সংজ্ঞা সহ:

data Mode = Major | Minor                 deriving (Show)
data Key = C | D | E | F | G | A | B      deriving (Show)
data Semitone = Flat | Natural | Sharp    deriving (Show)

data Note = Note Key Semitone             deriving (Show)
data Scale = Scale Note Mode              deriving (Show)
data Chord = Chord [Note]                 deriving (Show)

আপনি একটি ধারাবাহিকতা-পাসিং টাইপ প্রবর্তন করতে পারেন:

type Cont a r = (a -> r) -> r

এবং এ জাতীয় প্রকার তৈরি করতে আদিম নোট-বিল্ডিং প্রকারগুলি লিখুন Cont:

a, b, c :: Cont Note r
a = mkNote A
b = mkNote B
c = mkNote C
-- etc.
mkNote a f = f $ Note a Natural

flat, natural, sharp :: Note -> Cont Note r
flat    = mkSemi Flat
natural = mkSemi Natural
sharp   = mkSemi Sharp
mkSemi semi (Note k _) f = f $ Note k semi

তারপরে, স্কেল, নোট এবং জ্যাব বিল্ডিং ফাংশনগুলি দুটি Contপোস্টফিক্স আকারে (যেমন, ধারাবাহিকতা হিসাবে প্রেরণ করা হবে Cont) সরল ধরণের সমাধান করতে পারে :

major, minor :: Note -> Scale
major n = Scale n Major
minor n = Scale n Minor

note :: Note -> Note
note = id

বা উপসর্গ ফর্ম (অর্থাত্ Contযুক্তি হিসাবে গ্রহণ ):

chord :: [Cont Note [Note]] -> Chord
chord = Chord . foldr step []
  where step f acc = f (:acc)

এখন, আপনি লিখতে পারেন:

> c sharp note
Note C Sharp
> c note
Note C Natural
> c major
Scale (Note C Natural) Major
> b flat note
Note B Flat
> c sharp major
Scale (Note C Sharp) Major
> chord [a sharp, c]
Chord [Note A Sharp,Note C Natural]

মনে রাখবেন যে cনিজেই এর Showউদাহরণ নেই, তবে রয়েছে c note

Noteপ্রকারের পরিবর্তনের মাধ্যমে আপনি সহজেই দ্বৈত দুর্ঘটনাগুলিকে সমর্থন করতে পারেন (যেমন c sharp sharp, পৃথক পৃথক d) ইত্যাদি etc.


খুশী হলাম। আমি আসলে আমার সমস্যাটি সমাধান করার চেষ্টা করেছি Contতবে, আমি এটি A | B | C ...ফাংশন ব্যবহার না করে কনস্ট্রাক্টরের সাথে আটকে রাখার চেষ্টা করেছি । আমি এটি কাজ করতে পারিনি এবং এখনও এখনও বুঝতে পারছি না কেন, মান নির্মাতারা কেবল ফাংশন। আমি যদি আমার কীগুলির সামনে কোনও ফাংশন আটকে রাখতে পারি তবে অনেক কিছুই সম্ভব হয়। যদি ফাংশনটি হয় flip ($)তবে আমি আপনার প্যাটার্নটি পেয়েছি flip ($) B :: Cont Key r। আমার আসলটি aScale = scale C Majorখুব আলাদা নয়।
মার্টিন ড্রটজবার্গ

3

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

চতুরতার সাথে কাজ করার জন্য আপনি টাইপক্ল্যাস ব্যবহার করতে পারেন:

{-# LANGUAGE FlexibleInstances #-}

data Key = C | D | E | F | G | A | B deriving(Show)

data Mode = Major | Minor

data Scale = Scale Key Mode

class UsesKey t where
  c, d, e, f, g, a, b :: t

instance UsesKey Key where
  c = C
  d = D
  e = E
  f = F
  g = G
  a = A
  b = B

instance UsesKey (Mode -> Scale) where
  c = Scale C
  d = Scale D
  e = Scale E
  f = Scale F
  g = Scale G
  a = Scale A
  b = Scale B

aScale :: Scale
aScale = c Major

এখন, আপনি উপযুক্ত উদাহরণগুলির সংজ্ঞা দিয়ে অন্যান্য ধরণের জন্যও ছোট হাতের অক্ষর ব্যবহার করতে পারেন।

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