জিএইচসিআই-তে মাল্টি-লাইন কমান্ড


134

Gci তে মাল্টি-লাইন কমান্ড প্রবেশ করতে আমার সমস্যা হচ্ছে।

নিম্নলিখিত 2-লাইন কোডটি একটি ফাইল থেকে কাজ করে:

addTwo :: Int -> Int -> Int
addTwo x y = x + y

তবে আমি যখন ciসিএতে প্রবেশ করি তখন আমি একটি ত্রুটি পাই:

<interactive>:1:1: error:
    Variable not in scope: addTwo :: Int -> Int -> Int

আমি কোডটি ভিতরে রাখার চেষ্টা করেছি :{ ... :}, তবে তারা এই উদাহরণের জন্যও কাজ করছে না, কারণ এটি কেবল একটি লাইনে লাইনগুলি সংযোজন করছে, এটি হওয়া উচিত নয়।

আমি উইনজিএইচসিআই, সংস্করণ 2011.2.0.1 ব্যবহার করছি


উত্তর:


183

বেশিরভাগ সময়, আপনি নিজের জন্য স্বাক্ষর তৈরির জন্য টাইপ অনুক্রমের উপর নির্ভর করতে পারেন। আপনার উদাহরণে নিম্নলিখিতটি যথেষ্ট:

Prelude> let addTwo x y = x + y

আপনি যদি কোনও ধরণের স্বাক্ষর সহ সত্যই কোনও সংজ্ঞা চান, বা আপনার সংজ্ঞাটি একাধিক লাইনে বিস্তৃত হয়, আপনি এইটি করতে পারেন gci:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y 
Prelude| :}
Prelude> addTwo 4 7
11

নোট করুন যে আপনি এটি এক লাইনেও চেপে ধরতে পারেন:

Prelude> let addTwo :: Int -> Int -> Int ; addTwo x y = x + y

আপনি ডকুমেন্টেশনের প্রম্পট বিভাগে ইন্টারেক্টিভ মূল্যায়নে ghci এর সাথে ইন্টারঅ্যাক্ট করার বিষয়ে আরও জানতে পারেন ।


1
উভয় সমাধানের জন্য অনেক ধন্যবাদ। তবে আমার আরও একটি সম্পর্কিত প্রশ্ন রয়েছে: দ্বিতীয় লাইনে (অ্যাডটিউ-এর আগে) কেন চারটি শীর্ষস্থানীয় ফাঁকা প্রয়োজন? এবং এটি সঠিক হতে হবে, যদি কম বা বেশি ফাঁকা থাকে, তবে ত্রুটি আছে।
R71

9
@ রাগ letএকটি ব্লক শুরু করে; একটি ব্লকের প্রবেশগুলি ইন্ডেন্টেশন দ্বারা গোষ্ঠীভুক্ত করা হয়; এবং কোনও ব্লকের প্রথম অ-শ্বেতস্পেস অক্ষরটি ইন্ডেন্টেশন সেট করে যার দ্বারা তারা গোষ্ঠীভুক্ত হয়। যেহেতু প্রথম অ হোয়াইটস্পেস অক্ষর letব্লক উপরে aএর addTwo, ব্লক সমস্ত লাইন ঠিক হিসাবে গভীর যে হিসাবে ইন্ডেন্টযুক্ত করা আবশ্যক a
ড্যানিয়েল ওয়াগনার

ধন্যবাদ। আমি লক্ষ্য করেছি যে অন্য লেট / যেখানে ব্লক করে। এটি অন্যান্য ভাষাগুলির থেকে একটি বড় পার্থক্য যেখানে সাদা স্থান উপেক্ষা করা হয়, তাই এটি উপলব্ধি করতে আমার কিছুটা সমস্যা হয়েছিল।
R71

124

জিএইচসিআই এবং টাইপ করে এই সমস্যাটি সমাধান করুন :set +m:

Prelude> :set +m
Prelude> let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| 
Prelude> addTwo 1 3
4

গম্ভীর গর্জন।


এখানে কি হচ্ছে (এবং আমি বেশিরভাগ সাথে কথা বলছি আপনি , ব্যক্তি সাহায্যের জন্য googling যখন মাধ্যমে আপনার উপায় কাজ শিখুন আপনি একটি Haskell, ) যে GHCI একটি ইন্টারেক্টিভ পরিবেশ যেখানে আপনি মাছি উপর ফাংশন নামের বাইন্ডিং পরিবর্তন করছি না। আপনাকে আপনার ফাংশন সংজ্ঞাটি একটি letব্লকে মুড়ে রাখতে হবে, যাতে হাস্কেল জানে যে আপনি কোনও কিছুর সংজ্ঞা দিতে চলেছেন। :set +mকাপড় একাধিক লাইন জন্য সাধারণভাবে সংক্ষেপে হয় :{ কোড :} কনস্ট্রাক্ট।

হোয়াইটস্পেস ব্লকগুলিতেও তাৎপর্যপূর্ণ, সুতরাং চারটি স্পেসের জন্য চারটি স্পেসের জন্য অ্যাকাউন্ট নির্ধারণের জন্য আপনার টাইপ সংজ্ঞায়নের পরে আপনার ফাংশন সংজ্ঞাটি যুক্ত করতে হবে let


5
এত সহজ, তবে স্পষ্ট নয়। আমি যে বইটি ব্যবহার করছিলাম সেটিতে চিৎকার করতে চেয়েছিলাম যে পৃষ্ঠা 1 এ আমাকে না বলে!
টিম

2
একটি লিনাক্স শেল থেকে, echo ':set +m' >> ~/.ghciএই সেটিংটি অবিরাম করতে।
ট্রুটহোল্ডার 21

আপনি letনিজেই প্রথম লাইনে থাকতে পারেন তারপরে বাকী সমস্ত কিছুতেই ইন্টেন্ট করা লাগবে না। সাদা স্থান যেখানে সত্যই গণনা করা হয় সেখানে আপনার লাইনে অবশ্যই পিছনের জায়গা থাকতে হবে না। পিছনে সাদা স্থান অতিরিক্ত প্রবেশ হিসাবে গণনা করা হয় এবং মাল্টি-লাইন ব্লককে ভেঙে দেয়।
নেস


4

এর মতো GHCI সংস্করণ 8.0.1 , letআর REPL উপর ফাংশন নির্ধারণ প্রয়োজন।

সুতরাং এটি আপনার জন্য ভাল কাজ করা উচিত:

λ: addTwo x y = x + y
λ: addTwo 1 2
3
λ: :t addTwo
addTwo :: Num a => a -> a -> a

হাস্কেলের টাইপ-ইনফারেন্সেশন সাধারণ টাইপিং সরবরাহ করে যা ভাসমানদের জন্যও কাজ করে:

λ: addTwo 2.0 1.0
3.0

যদি আপনাকে অবশ্যই নিজের নিজস্ব টাইপ সরবরাহ করতে হয় তবে মনে হয় আপনাকে মাল্টলাইন ইনপুট (জিএইচসিআইতে মাল্টলাইন ইনপুট সক্ষম করতে letব্যবহার করুন) এর সাথে মিলিত ব্যবহার :set +mকরতে হবে:

λ: let addTwo :: Int -> Int -> Int
 |     addTwo x y = x + y
 | 
λ: addTwo 1 2
3

Intআপনার অ-পলিমারফিক টাইপিংয়ের কারণে আপনি যদি কিছু পাস করার চেষ্টা করেন তবে আপনি ত্রুটিগুলি পেয়ে যাবেন :

λ: addTwo 2.0 1.0

<interactive>:34:8: error:
     No instance for (Fractional Int) arising from the literal 2.0
     In the first argument of addTwo’, namely 2.0
      In the expression: addTwo 2.0 1.0
      In an equation for it’: it = addTwo 2.0 1.0

2

অ্যারন হলের উত্তরটি প্রসারিত করতে , GHCi 8.4.4 সংস্করণে কমপক্ষে, আপনি letযদি :{ :}স্টাইলটি ব্যবহার করেন তবে টাইপ ডিক্লেয়ারেশন সহ আপনার ব্যবহার করার দরকার নেই । এর অর্থ হ'ল প্রতিটি পরবর্তী লাইনে 4-স্পেস ইন্ডেন্টেশন যুক্ত করার জন্য আপনাকে চিন্তিত হওয়ার দরকার নেই let, দীর্ঘতর ফাংশনগুলি টাইপ করা আরও সহজ করে তোলে, বা অনেক ক্ষেত্রে অনুলিপি-পেস্ট করা হয় (যেহেতু মূল উত্সটি সম্ভবত থাকবে না) সঠিক ইন্ডেন্টেশন):

λ: :{
 | addTwo :: Int -> Int -> Int
 | addTwo x y = x + y
 | :}
λ: addTwo 1 2
3

হালনাগাদ

বিকল্প হিসাবে আপনি একাধিক-লাইন ইনপুট মোডটি চালু করতে পারেন :set +m, তারপরে letনিজেই টাইপ করুন, এন্টার টিপুন, তারপরে কোনও ইন্ডেন্টেশন ছাড়াই সংজ্ঞা সংযুক্ত করুন।

তবে এটি কিছু কোড ব্লকের সাথে কাজ করছে বলে মনে হয় না যেমন:

class Box a where
  mkBox :: a -> Boxes.Box

কিন্তু :{, :}কৌশলটি করে।


1
আসলে, এর আগেও, আপনি টাইপ করতে পারতেন :{, তারপরে letনিজেই পরবর্তী লাইনে , তারপরে আপনার সংজ্ঞাটি কোনও যোগ করা ইন্ডেন্টেশন ছাড়াই পেস্ট করুন, তারপরে বন্ধ করুন :}। :) এবং মাল্টি-লাইন ইনপুট মোড সেট ( :set +m) সহ আপনার এমনকি যতক্ষণ না লাইনগুলিতে কোনও পিছনে স্থান নেই সেখানে ধনুর্বন্ধনী কমান্ডগুলির প্রয়োজন নেই।
নেস

আহ, তাই :set +mআপনি কি কেবল letনিজের লাইনে ব্যবহার করতে পারেন ? সুতরাং আপনি পারেন - যে দুর্দান্ত। ধন্যবাদ.
ডেভিডা

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